Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid
[simgrid.git] / src / smpi / smpi_pmpi.c
1
2 /* Copyright (c) 2007-2014. The SimGrid Team.
3  * All rights reserved.                                                     */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "private.h"
9 #include "smpi_mpi_dt_private.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi,
12                                 "Logging specific to SMPI (pmpi)");
13
14 #ifdef HAVE_TRACING
15 //this function need to be here because of the calls to smpi_bench
16 void TRACE_smpi_set_category(const char *category)
17 {
18   //need to end bench otherwise categories for execution tasks are wrong
19   smpi_bench_end();
20   TRACE_internal_smpi_set_category (category);
21   //begin bench after changing process's category
22   smpi_bench_begin();
23 }
24 #endif
25
26 /* PMPI User level calls */
27
28 int PMPI_Init(int *argc, char ***argv)
29 {
30   smpi_process_init(argc, argv);
31   smpi_process_mark_as_initialized();
32 #ifdef HAVE_TRACING
33   int rank = smpi_process_index();
34   TRACE_smpi_init(rank);
35   TRACE_smpi_computing_init(rank);
36   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
37   extra->type = TRACING_INIT;
38   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
39   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
40 #endif
41   smpi_bench_begin();
42   return MPI_SUCCESS;
43 }
44
45 int PMPI_Finalize(void)
46 {
47   smpi_bench_end();
48 #ifdef HAVE_TRACING
49   int rank = smpi_process_index();
50   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
51   extra->type = TRACING_FINALIZE;
52   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
53 #endif
54   smpi_process_finalize();
55 #ifdef HAVE_TRACING
56   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
57   TRACE_smpi_finalize(smpi_process_index());
58 #endif
59   smpi_process_destroy();
60   return MPI_SUCCESS;
61 }
62
63 int PMPI_Finalized(int* flag)
64 {
65   *flag=smpi_process_finalized();
66   return MPI_SUCCESS;
67 }
68
69 int PMPI_Get_version (int *version,int *subversion){
70   *version = MPI_VERSION;
71   *subversion= MPI_SUBVERSION;
72   return MPI_SUCCESS;
73 }
74
75 int PMPI_Get_library_version (char *version,int *len){
76   int retval = MPI_SUCCESS;
77   smpi_bench_end();
78   snprintf(version,MPI_MAX_LIBRARY_VERSION_STRING,"SMPI Version %d.%d. Copyright The Simgrid Team 2007-2014",SIMGRID_VERSION_MAJOR,
79           SIMGRID_VERSION_MINOR);
80   *len = strlen(version) > MPI_MAX_LIBRARY_VERSION_STRING ? MPI_MAX_LIBRARY_VERSION_STRING : strlen(version);
81   smpi_bench_begin();
82   return retval;
83 }
84
85 int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
86 {
87   if (provided != NULL) {
88     *provided = MPI_THREAD_MULTIPLE;
89   }
90   return MPI_Init(argc, argv);
91 }
92
93 int PMPI_Query_thread(int *provided)
94 {
95   int retval = 0;
96
97   if (provided == NULL) {
98     retval = MPI_ERR_ARG;
99   } else {
100     *provided = MPI_THREAD_MULTIPLE;
101     retval = MPI_SUCCESS;
102   }
103   return retval;
104 }
105
106 int PMPI_Is_thread_main(int *flag)
107 {
108   int retval = 0;
109
110   if (flag == NULL) {
111     retval = MPI_ERR_ARG;
112   } else {
113     *flag = smpi_process_index() == 0;
114     retval = MPI_SUCCESS;
115   }
116   return retval;
117 }
118
119 int PMPI_Abort(MPI_Comm comm, int errorcode)
120 {
121   smpi_bench_end();
122   smpi_process_destroy();
123   // FIXME: should kill all processes in comm instead
124   simcall_process_kill(SIMIX_process_self());
125   return MPI_SUCCESS;
126 }
127
128 double PMPI_Wtime(void)
129 {
130   double time;
131   if (smpi_process_initialized() && !smpi_process_finalized() && !smpi_process_get_sampling()) {
132     smpi_bench_end();
133     time = SIMIX_get_clock();
134     smpi_bench_begin();
135   } else {
136     time = SIMIX_get_clock();
137   }
138   return time;
139 }
140
141 extern double sg_maxmin_precision;
142 double PMPI_Wtick(void)
143 {
144   return sg_maxmin_precision;
145 }
146
147 int PMPI_Address(void *location, MPI_Aint * address)
148 {
149   int retval = 0;
150
151   if (!address) {
152     retval = MPI_ERR_ARG;
153   } else {
154     *address = (MPI_Aint) location;
155     retval = MPI_SUCCESS;
156   }
157   return retval;
158 }
159
160 int PMPI_Get_address(void *location, MPI_Aint * address)
161 {
162   return PMPI_Address(location, address);
163 }
164
165 int PMPI_Type_free(MPI_Datatype * datatype)
166 {
167   int retval = 0;
168   /* Free a predefined datatype is an error according to the standard, and
169      should be checked for */
170   if (*datatype == MPI_DATATYPE_NULL) {
171     retval = MPI_ERR_ARG;
172   } else {
173     smpi_datatype_free(datatype);
174     retval = MPI_SUCCESS;
175   }
176   return retval;
177 }
178
179 int PMPI_Type_size(MPI_Datatype datatype, int *size)
180 {
181   int retval = 0;
182
183   if (datatype == MPI_DATATYPE_NULL) {
184     retval = MPI_ERR_TYPE;
185   } else if (size == NULL) {
186     retval = MPI_ERR_ARG;
187   } else {
188     *size = (int) smpi_datatype_size(datatype);
189     retval = MPI_SUCCESS;
190   }
191   return retval;
192 }
193
194 int PMPI_Type_get_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
195 {
196   int retval = 0;
197
198   if (datatype == MPI_DATATYPE_NULL) {
199     retval = MPI_ERR_TYPE;
200   } else if (lb == NULL || extent == NULL) {
201     retval = MPI_ERR_ARG;
202   } else {
203     retval = smpi_datatype_extent(datatype, lb, extent);
204   }
205   return retval;
206 }
207
208 int PMPI_Type_get_true_extent(MPI_Datatype datatype, MPI_Aint * lb, MPI_Aint * extent)
209 {
210   return PMPI_Type_get_extent(datatype, lb, extent);
211 }
212
213 int PMPI_Type_extent(MPI_Datatype datatype, MPI_Aint * extent)
214 {
215   int retval = 0;
216
217   if (datatype == MPI_DATATYPE_NULL) {
218     retval = MPI_ERR_TYPE;
219   } else if (extent == NULL) {
220     retval = MPI_ERR_ARG;
221   } else {
222     *extent = smpi_datatype_get_extent(datatype);
223     retval = MPI_SUCCESS;
224   }
225   return retval;
226 }
227
228 int PMPI_Type_lb(MPI_Datatype datatype, MPI_Aint * disp)
229 {
230   int retval = 0;
231
232   if (datatype == MPI_DATATYPE_NULL) {
233     retval = MPI_ERR_TYPE;
234   } else if (disp == NULL) {
235     retval = MPI_ERR_ARG;
236   } else {
237     *disp = smpi_datatype_lb(datatype);
238     retval = MPI_SUCCESS;
239   }
240   return retval;
241 }
242
243 int PMPI_Type_ub(MPI_Datatype datatype, MPI_Aint * disp)
244 {
245   int retval = 0;
246
247   if (datatype == MPI_DATATYPE_NULL) {
248     retval = MPI_ERR_TYPE;
249   } else if (disp == NULL) {
250     retval = MPI_ERR_ARG;
251   } else {
252     *disp = smpi_datatype_ub(datatype);
253     retval = MPI_SUCCESS;
254   }
255   return retval;
256 }
257
258 int PMPI_Type_dup(MPI_Datatype datatype, MPI_Datatype *newtype){
259   int retval = 0;
260
261   if (datatype == MPI_DATATYPE_NULL) {
262     retval = MPI_ERR_TYPE;
263   } else {
264     *newtype = smpi_datatype_dup(datatype);
265     retval = MPI_SUCCESS;
266   }
267   return retval;
268 }
269
270 int PMPI_Op_create(MPI_User_function * function, int commute, MPI_Op * op)
271 {
272   int retval = 0;
273
274   if (function == NULL || op == NULL) {
275     retval = MPI_ERR_ARG;
276   } else {
277     *op = smpi_op_new(function, commute);
278     retval = MPI_SUCCESS;
279   }
280   return retval;
281 }
282
283 int PMPI_Op_free(MPI_Op * op)
284 {
285   int retval = 0;
286
287   if (op == NULL) {
288     retval = MPI_ERR_ARG;
289   } else if (*op == MPI_OP_NULL) {
290     retval = MPI_ERR_OP;
291   } else {
292     smpi_op_destroy(*op);
293     *op = MPI_OP_NULL;
294     retval = MPI_SUCCESS;
295   }
296   return retval;
297 }
298
299 int PMPI_Group_free(MPI_Group * group)
300 {
301   int retval = 0;
302
303   if (group == NULL) {
304     retval = MPI_ERR_ARG;
305   } else {
306     smpi_group_destroy(*group);
307     *group = MPI_GROUP_NULL;
308     retval = MPI_SUCCESS;
309   }
310   return retval;
311 }
312
313 int PMPI_Group_size(MPI_Group group, int *size)
314 {
315   int retval = 0;
316
317   if (group == MPI_GROUP_NULL) {
318     retval = MPI_ERR_GROUP;
319   } else if (size == NULL) {
320     retval = MPI_ERR_ARG;
321   } else {
322     *size = smpi_group_size(group);
323     retval = MPI_SUCCESS;
324   }
325   return retval;
326 }
327
328 int PMPI_Group_rank(MPI_Group group, int *rank)
329 {
330   int retval = 0;
331
332   if (group == MPI_GROUP_NULL) {
333     retval = MPI_ERR_GROUP;
334   } else if (rank == NULL) {
335     retval = MPI_ERR_ARG;
336   } else {
337     *rank = smpi_group_rank(group, smpi_process_index());
338     retval = MPI_SUCCESS;
339   }
340   return retval;
341 }
342
343 int PMPI_Group_translate_ranks(MPI_Group group1, int n, int *ranks1,
344                               MPI_Group group2, int *ranks2)
345 {
346   int retval, i, index;
347   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
348     retval = MPI_ERR_GROUP;
349   } else {
350     for (i = 0; i < n; i++) {
351       if(ranks1[i]==MPI_PROC_NULL){
352         ranks2[i]=MPI_PROC_NULL;
353       }else{
354         index = smpi_group_index(group1, ranks1[i]);
355         ranks2[i] = smpi_group_rank(group2, index);
356       }
357     }
358     retval = MPI_SUCCESS;
359   }
360   return retval;
361 }
362
363 int PMPI_Group_compare(MPI_Group group1, MPI_Group group2, int *result)
364 {
365   int retval = 0;
366
367   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
368     retval = MPI_ERR_GROUP;
369   } else if (result == NULL) {
370     retval = MPI_ERR_ARG;
371   } else {
372     *result = smpi_group_compare(group1, group2);
373     retval = MPI_SUCCESS;
374   }
375   return retval;
376 }
377
378 int PMPI_Group_union(MPI_Group group1, MPI_Group group2,
379                     MPI_Group * newgroup)
380 {
381   int retval, i, proc1, proc2, size, size2;
382
383   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
384     retval = MPI_ERR_GROUP;
385   } else if (newgroup == NULL) {
386     retval = MPI_ERR_ARG;
387   } else {
388     size = smpi_group_size(group1);
389     size2 = smpi_group_size(group2);
390     for (i = 0; i < size2; i++) {
391       proc2 = smpi_group_index(group2, i);
392       proc1 = smpi_group_rank(group1, proc2);
393       if (proc1 == MPI_UNDEFINED) {
394         size++;
395       }
396     }
397     if (size == 0) {
398       *newgroup = MPI_GROUP_EMPTY;
399     } else {
400       *newgroup = smpi_group_new(size);
401       size2 = smpi_group_size(group1);
402       for (i = 0; i < size2; i++) {
403         proc1 = smpi_group_index(group1, i);
404         smpi_group_set_mapping(*newgroup, proc1, i);
405       }
406       for (i = size2; i < size; i++) {
407         proc2 = smpi_group_index(group2, i - size2);
408         smpi_group_set_mapping(*newgroup, proc2, i);
409       }
410     }
411     retval = MPI_SUCCESS;
412   }
413   return retval;
414 }
415
416 int PMPI_Group_intersection(MPI_Group group1, MPI_Group group2,
417                            MPI_Group * newgroup)
418 {
419   int retval, i, proc1, proc2, size;
420
421   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
422     retval = MPI_ERR_GROUP;
423   } else if (newgroup == NULL) {
424     retval = MPI_ERR_ARG;
425   } else {
426     size = smpi_group_size(group2);
427     for (i = 0; i < size; i++) {
428       proc2 = smpi_group_index(group2, i);
429       proc1 = smpi_group_rank(group1, proc2);
430       if (proc1 == MPI_UNDEFINED) {
431         size--;
432       }
433     }
434     if (size == 0) {
435       *newgroup = MPI_GROUP_EMPTY;
436     } else {
437       *newgroup = smpi_group_new(size);
438       int j=0;
439       for (i = 0; i < smpi_group_size(group2); i++) {
440         proc2 = smpi_group_index(group2, i);
441         proc1 = smpi_group_rank(group1, proc2);
442         if (proc1 != MPI_UNDEFINED) {
443           smpi_group_set_mapping(*newgroup, proc2, j);
444           j++;
445         }
446       }
447     }
448     retval = MPI_SUCCESS;
449   }
450   return retval;
451 }
452
453 int PMPI_Group_difference(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup)
454 {
455   int retval, i, proc1, proc2, size, size2;
456
457   if (group1 == MPI_GROUP_NULL || group2 == MPI_GROUP_NULL) {
458     retval = MPI_ERR_GROUP;
459   } else if (newgroup == NULL) {
460     retval = MPI_ERR_ARG;
461   } else {
462     size = size2 = smpi_group_size(group1);
463     for (i = 0; i < size2; i++) {
464       proc1 = smpi_group_index(group1, i);
465       proc2 = smpi_group_rank(group2, proc1);
466       if (proc2 != MPI_UNDEFINED) {
467         size--;
468       }
469     }
470     if (size == 0) {
471       *newgroup = MPI_GROUP_EMPTY;
472     } else {
473       *newgroup = smpi_group_new(size);
474       for (i = 0; i < size2; i++) {
475         proc1 = smpi_group_index(group1, i);
476         proc2 = smpi_group_rank(group2, proc1);
477         if (proc2 == MPI_UNDEFINED) {
478           smpi_group_set_mapping(*newgroup, proc1, i);
479         }
480       }
481     }
482     retval = MPI_SUCCESS;
483   }
484   return retval;
485 }
486
487 int PMPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
488 {
489   int retval, i, index;
490
491   if (group == MPI_GROUP_NULL) {
492     retval = MPI_ERR_GROUP;
493   } else if (newgroup == NULL) {
494     retval = MPI_ERR_ARG;
495   } else {
496     if (n == 0) {
497       *newgroup = MPI_GROUP_EMPTY;
498     } else if (n == smpi_group_size(group)) {
499       *newgroup = group;
500       if(group!= smpi_comm_group(MPI_COMM_WORLD)
501                 && group != MPI_GROUP_NULL
502                 && group != smpi_comm_group(MPI_COMM_SELF)
503                 && group != MPI_GROUP_EMPTY)
504       smpi_group_use(group);
505     } else {
506       *newgroup = smpi_group_new(n);
507       for (i = 0; i < n; i++) {
508         index = smpi_group_index(group, ranks[i]);
509         smpi_group_set_mapping(*newgroup, index, i);
510       }
511     }
512     retval = MPI_SUCCESS;
513   }
514   return retval;
515 }
516
517 int PMPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group * newgroup)
518 {
519   int retval, i, j, newsize, oldsize, index;
520
521   if (group == MPI_GROUP_NULL) {
522     retval = MPI_ERR_GROUP;
523   } else if (newgroup == NULL) {
524     retval = MPI_ERR_ARG;
525   } else {
526     if (n == 0) {
527       *newgroup = group;
528       if(group!= smpi_comm_group(MPI_COMM_WORLD)
529                 && group != MPI_GROUP_NULL
530                 && group != smpi_comm_group(MPI_COMM_SELF)
531                 && group != MPI_GROUP_EMPTY)
532       smpi_group_use(group);
533     } else if (n == smpi_group_size(group)) {
534       *newgroup = MPI_GROUP_EMPTY;
535     } else {
536       oldsize=smpi_group_size(group);
537       newsize = oldsize - n;
538       *newgroup = smpi_group_new(newsize);
539
540       int* to_exclude=xbt_new0(int, smpi_group_size(group));
541       for(i=0; i<oldsize; i++)
542         to_exclude[i]=0;
543       for(i=0; i<n; i++)
544         to_exclude[ranks[i]]=1;
545
546       j=0;
547       for(i=0; i<oldsize; i++){
548         if(to_exclude[i]==0){
549           index = smpi_group_index(group, i);
550           smpi_group_set_mapping(*newgroup, index, j);
551           j++;
552         }
553       }
554
555       xbt_free(to_exclude);
556     }
557     retval = MPI_SUCCESS;
558   }
559   return retval;
560 }
561
562 int PMPI_Group_range_incl(MPI_Group group, int n, int ranges[][3],
563                          MPI_Group * newgroup)
564 {
565   int retval, i, j, rank, size, index;
566
567   if (group == MPI_GROUP_NULL) {
568     retval = MPI_ERR_GROUP;
569   } else if (newgroup == NULL) {
570     retval = MPI_ERR_ARG;
571   } else {
572     if (n == 0) {
573       *newgroup = MPI_GROUP_EMPTY;
574     } else {
575       size = 0;
576       for (i = 0; i < n; i++) {
577         for (rank = ranges[i][0];       /* First */
578              rank >= 0; /* Last */
579               ) {
580           size++;
581
582           rank += ranges[i][2]; /* Stride */
583           if (ranges[i][0]<ranges[i][1]){
584               if(rank > ranges[i][1])
585                 break;
586           }else{
587               if(rank < ranges[i][1])
588                 break;
589           }
590         }
591       }
592
593       *newgroup = smpi_group_new(size);
594       j = 0;
595       for (i = 0; i < n; i++) {
596         for (rank = ranges[i][0];     /* First */
597              rank >= 0; /* Last */
598              ) {
599           index = smpi_group_index(group, rank);
600           smpi_group_set_mapping(*newgroup, index, j);
601           j++;
602           rank += ranges[i][2]; /* Stride */
603           if (ranges[i][0]<ranges[i][1]){
604             if(rank > ranges[i][1])
605               break;
606           }else{
607             if(rank < ranges[i][1])
608               break;
609           }
610         }
611       }
612     }
613     retval = MPI_SUCCESS;
614   }
615   return retval;
616 }
617
618 int PMPI_Group_range_excl(MPI_Group group, int n, int ranges[][3],
619                          MPI_Group * newgroup)
620 {
621   int retval, i, rank, newrank,oldrank, size, index, add;
622
623   if (group == MPI_GROUP_NULL) {
624     retval = MPI_ERR_GROUP;
625   } else if (newgroup == NULL) {
626     retval = MPI_ERR_ARG;
627   } else {
628     if (n == 0) {
629       *newgroup = group;
630       if(group!= smpi_comm_group(MPI_COMM_WORLD)
631                 && group != MPI_GROUP_NULL
632                 && group != smpi_comm_group(MPI_COMM_SELF)
633                 && group != MPI_GROUP_EMPTY)
634       smpi_group_use(group);
635     } else {
636       size = smpi_group_size(group);
637       for (i = 0; i < n; i++) {
638         for (rank = ranges[i][0];       /* First */
639              rank >= 0; /* Last */
640               ) {
641           size--;
642
643           rank += ranges[i][2]; /* Stride */
644           if (ranges[i][0]<ranges[i][1]){
645               if(rank > ranges[i][1])
646                 break;
647           }else{
648               if(rank < ranges[i][1])
649                 break;
650           }
651         }
652       }
653       if (size == 0) {
654         *newgroup = MPI_GROUP_EMPTY;
655       } else {
656         *newgroup = smpi_group_new(size);
657         newrank=0;
658         oldrank=0;
659         while (newrank < size) {
660           add=1;
661           for (i = 0; i < n; i++) {
662             for (rank = ranges[i][0];rank >= 0;){
663               if(rank==oldrank){
664                   add=0;
665                   break;
666               }
667
668               rank += ranges[i][2]; /* Stride */
669
670               if (ranges[i][0]<ranges[i][1]){
671                   if(rank > ranges[i][1])
672                     break;
673               }else{
674                   if(rank < ranges[i][1])
675                     break;
676               }
677             }
678           }
679           if(add==1){
680             index = smpi_group_index(group, oldrank);
681             smpi_group_set_mapping(*newgroup, index, newrank);
682             newrank++;
683           }
684           oldrank++;
685         }
686       }
687     }
688
689     retval = MPI_SUCCESS;
690   }
691   return retval;
692 }
693
694 int PMPI_Comm_rank(MPI_Comm comm, int *rank)
695 {
696   int retval = 0;
697   if (comm == MPI_COMM_NULL) {
698     retval = MPI_ERR_COMM;
699   } else if (rank == NULL) {
700     retval = MPI_ERR_ARG;
701   } else {
702     *rank = smpi_comm_rank(comm);
703     retval = MPI_SUCCESS;
704   }
705   return retval;
706 }
707
708 int PMPI_Comm_size(MPI_Comm comm, int *size)
709 {
710   int retval = 0;
711   if (comm == MPI_COMM_NULL) {
712     retval = MPI_ERR_COMM;
713   } else if (size == NULL) {
714     retval = MPI_ERR_ARG;
715   } else {
716     *size = smpi_comm_size(comm);
717     retval = MPI_SUCCESS;
718   }
719   return retval;
720 }
721
722 int PMPI_Comm_get_name (MPI_Comm comm, char* name, int* len)
723 {
724   int retval = 0;
725
726   if (comm == MPI_COMM_NULL)  {
727     retval = MPI_ERR_COMM;
728   } else if (name == NULL || len == NULL)  {
729     retval = MPI_ERR_ARG;
730   } else {
731     smpi_comm_get_name(comm, name, len);
732     retval = MPI_SUCCESS;
733   }
734   return retval;
735 }
736
737 int PMPI_Comm_group(MPI_Comm comm, MPI_Group * group)
738 {
739   int retval = 0;
740
741   if (comm == MPI_COMM_NULL) {
742     retval = MPI_ERR_COMM;
743   } else if (group == NULL) {
744     retval = MPI_ERR_ARG;
745   } else {
746     *group = smpi_comm_group(comm);
747     if(*group!= smpi_comm_group(MPI_COMM_WORLD)
748               && *group != MPI_GROUP_NULL
749               && *group != smpi_comm_group(MPI_COMM_SELF)
750               && *group != MPI_GROUP_EMPTY)
751     smpi_group_use(*group);
752     retval = MPI_SUCCESS;
753   }
754   return retval;
755 }
756
757 int PMPI_Comm_compare(MPI_Comm comm1, MPI_Comm comm2, int *result)
758 {
759   int retval = 0;
760
761   if (comm1 == MPI_COMM_NULL || comm2 == MPI_COMM_NULL) {
762     retval = MPI_ERR_COMM;
763   } else if (result == NULL) {
764     retval = MPI_ERR_ARG;
765   } else {
766     if (comm1 == comm2) {       /* Same communicators means same groups */
767       *result = MPI_IDENT;
768     } else {
769       *result =
770           smpi_group_compare(smpi_comm_group(comm1),
771                              smpi_comm_group(comm2));
772       if (*result == MPI_IDENT) {
773         *result = MPI_CONGRUENT;
774       }
775     }
776     retval = MPI_SUCCESS;
777   }
778   return retval;
779 }
780
781 int PMPI_Comm_dup(MPI_Comm comm, MPI_Comm * newcomm)
782 {
783   int retval = 0;
784
785   if (comm == MPI_COMM_NULL) {
786     retval = MPI_ERR_COMM;
787   } else if (newcomm == NULL) {
788     retval = MPI_ERR_ARG;
789   } else {
790     *newcomm = smpi_comm_new(smpi_comm_group(comm), smpi_comm_topo(comm));
791     retval = MPI_SUCCESS;
792   }
793   return retval;
794 }
795
796 int PMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm)
797 {
798   int retval = 0;
799
800   if (comm == MPI_COMM_NULL) {
801     retval = MPI_ERR_COMM;
802   } else if (group == MPI_GROUP_NULL) {
803     retval = MPI_ERR_GROUP;
804   } else if (newcomm == NULL) {
805     retval = MPI_ERR_ARG;
806   } else if(smpi_group_rank(group,smpi_process_index())==MPI_UNDEFINED){
807     *newcomm= MPI_COMM_NULL;
808     retval = MPI_SUCCESS;
809   }else{
810
811     *newcomm = smpi_comm_new(group, NULL);
812     retval = MPI_SUCCESS;
813   }
814   return retval;
815 }
816
817 int PMPI_Comm_free(MPI_Comm * comm)
818 {
819   int retval = 0;
820
821   if (comm == NULL) {
822     retval = MPI_ERR_ARG;
823   } else if (*comm == MPI_COMM_NULL) {
824     retval = MPI_ERR_COMM;
825   } else {
826     smpi_comm_destroy(*comm);
827     *comm = MPI_COMM_NULL;
828     retval = MPI_SUCCESS;
829   }
830   return retval;
831 }
832
833 int PMPI_Comm_disconnect(MPI_Comm * comm)
834 {
835   /* TODO: wait until all communication in comm are done */
836   int retval = 0;
837
838   if (comm == NULL) {
839     retval = MPI_ERR_ARG;
840   } else if (*comm == MPI_COMM_NULL) {
841     retval = MPI_ERR_COMM;
842   } else {
843     smpi_comm_destroy(*comm);
844     *comm = MPI_COMM_NULL;
845     retval = MPI_SUCCESS;
846   }
847   return retval;
848 }
849
850 int PMPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm* comm_out)
851 {
852   int retval = 0;
853   smpi_bench_end();
854
855   if (comm_out == NULL) {
856     retval = MPI_ERR_ARG;
857   } else if (comm == MPI_COMM_NULL) {
858     retval = MPI_ERR_COMM;
859   } else {
860     *comm_out = smpi_comm_split(comm, color, key);
861     retval = MPI_SUCCESS;
862   }
863   smpi_bench_begin();
864
865   return retval;
866 }
867
868 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst,
869                    int tag, MPI_Comm comm, MPI_Request * request)
870 {
871   int retval = 0;
872
873   smpi_bench_end();
874   if (request == NULL) {
875       retval = MPI_ERR_ARG;
876   } else if (comm == MPI_COMM_NULL) {
877       retval = MPI_ERR_COMM;
878   } else if (!is_datatype_valid(datatype)) {
879       retval = MPI_ERR_TYPE;
880   } else if (dst == MPI_PROC_NULL) {
881       retval = MPI_SUCCESS;
882   } else {
883       *request = smpi_mpi_send_init(buf, count, datatype, dst, tag, comm);
884       retval = MPI_SUCCESS;
885   }
886   smpi_bench_begin();
887   if (retval != MPI_SUCCESS && request)
888     *request = MPI_REQUEST_NULL;
889   return retval;
890 }
891
892 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src,
893                    int tag, MPI_Comm comm, MPI_Request * request)
894 {
895   int retval = 0;
896
897   smpi_bench_end();
898   if (request == NULL) {
899     retval = MPI_ERR_ARG;
900   } else if (comm == MPI_COMM_NULL) {
901     retval = MPI_ERR_COMM;
902   } else if (!is_datatype_valid(datatype)) {
903       retval = MPI_ERR_TYPE;
904   } else if (src == MPI_PROC_NULL) {
905     retval = MPI_SUCCESS;
906   } else {
907     *request = smpi_mpi_recv_init(buf, count, datatype, src, tag, comm);
908     retval = MPI_SUCCESS;
909   }
910   smpi_bench_begin();
911   if (retval != MPI_SUCCESS && request)
912     *request = MPI_REQUEST_NULL;
913   return retval;
914 }
915
916 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype,
917                     int dst, int tag, MPI_Comm comm, MPI_Request* request)
918 {
919   int retval = 0;
920
921   smpi_bench_end();
922   if (request == NULL) {
923     retval = MPI_ERR_ARG;
924   } else if (comm == MPI_COMM_NULL) {
925     retval = MPI_ERR_COMM;
926   } else if (!is_datatype_valid(datatype)) {
927       retval = MPI_ERR_TYPE;
928   } else if (dst == MPI_PROC_NULL) {
929     retval = MPI_SUCCESS;
930   } else {
931     *request = smpi_mpi_ssend_init(buf, count, datatype, dst, tag, comm);
932     retval = MPI_SUCCESS;
933   }
934   smpi_bench_begin();
935   if (retval != MPI_SUCCESS && request)
936     *request = MPI_REQUEST_NULL;
937   return retval;
938 }
939
940 int PMPI_Start(MPI_Request * request)
941 {
942   int retval = 0;
943
944   smpi_bench_end();
945   if (request == NULL || *request == MPI_REQUEST_NULL) {
946     retval = MPI_ERR_REQUEST;
947   } else {
948     smpi_mpi_start(*request);
949     retval = MPI_SUCCESS;
950   }
951   smpi_bench_begin();
952   return retval;
953 }
954
955 int PMPI_Startall(int count, MPI_Request * requests)
956 {
957   int retval;
958   int i = 0;
959   smpi_bench_end();
960   if (requests == NULL) {
961     retval = MPI_ERR_ARG;
962   } else {
963     retval = MPI_SUCCESS;
964     for (i = 0 ;  i < count ; i++) {
965       if(requests[i] == MPI_REQUEST_NULL) {
966         retval = MPI_ERR_REQUEST;
967       }
968     }
969     if(retval != MPI_ERR_REQUEST) {
970       smpi_mpi_startall(count, requests);
971     }
972   }
973   smpi_bench_begin();
974   return retval;
975 }
976
977 int PMPI_Request_free(MPI_Request * request)
978 {
979   int retval = 0;
980
981   smpi_bench_end();
982   if (*request == MPI_REQUEST_NULL) {
983     retval = MPI_ERR_ARG;
984   } else {
985     smpi_mpi_request_free(request);
986     retval = MPI_SUCCESS;
987   }
988   smpi_bench_begin();
989   return retval;
990 }
991
992 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src,
993                int tag, MPI_Comm comm, MPI_Request * request)
994 {
995   int retval = 0;
996
997   smpi_bench_end();
998
999   if (request == NULL) {
1000     retval = MPI_ERR_ARG;
1001   } else if (comm == MPI_COMM_NULL) {
1002     retval = MPI_ERR_COMM;
1003   } else if (src == MPI_PROC_NULL) {
1004     *request = MPI_REQUEST_NULL;
1005     retval = MPI_SUCCESS;
1006   } else if (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0)){
1007     retval = MPI_ERR_COMM;
1008   } else if (count < 0) {
1009     retval = MPI_ERR_COUNT;
1010   } else if (buf==NULL && count > 0) {
1011     retval = MPI_ERR_COUNT;
1012   } else if (!is_datatype_valid(datatype)) {
1013       retval = MPI_ERR_TYPE;
1014   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1015     retval = MPI_ERR_TAG;
1016   } else {
1017
1018 #ifdef HAVE_TRACING
1019     int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1020     int src_traced = smpi_group_index(smpi_comm_group(comm), src);
1021
1022     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1023     extra->type = TRACING_IRECV;
1024     extra->send_size = count;
1025     extra->src = src_traced;
1026     extra->dst = rank;
1027     extra->datatype1 = encode_datatype(datatype);
1028     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
1029 #endif
1030
1031     *request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm);
1032     retval = MPI_SUCCESS;
1033
1034 #ifdef HAVE_TRACING
1035     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
1036     (*request)->recv = 1;
1037 #endif
1038   }
1039
1040   smpi_bench_begin();
1041   if (retval != MPI_SUCCESS && request)
1042     *request = MPI_REQUEST_NULL;
1043   return retval;
1044 }
1045
1046
1047 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst,
1048                int tag, MPI_Comm comm, MPI_Request * request)
1049 {
1050   int retval = 0;
1051
1052   smpi_bench_end();
1053   if (request == NULL) {
1054     retval = MPI_ERR_ARG;
1055   } else if (comm == MPI_COMM_NULL) {
1056     retval = MPI_ERR_COMM;
1057   } else if (dst == MPI_PROC_NULL) {
1058     *request = MPI_REQUEST_NULL;
1059     retval = MPI_SUCCESS;
1060   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1061     retval = MPI_ERR_RANK;
1062   } else if (count < 0) {
1063     retval = MPI_ERR_COUNT;
1064   } else if (buf==NULL && count > 0) {
1065     retval = MPI_ERR_COUNT;
1066   } else if (!is_datatype_valid(datatype)) {
1067       retval = MPI_ERR_TYPE;
1068   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1069     retval = MPI_ERR_TAG;
1070   } else {
1071
1072 #ifdef HAVE_TRACING
1073     int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1074     int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1075
1076     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1077     extra->type = TRACING_ISEND;
1078     extra->send_size = count;
1079     extra->src = rank;
1080     extra->dst = dst_traced;
1081     extra->datatype1 = encode_datatype(datatype);
1082     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1083     TRACE_smpi_send(rank, rank, dst_traced, count*smpi_datatype_size(datatype));
1084 #endif
1085
1086     *request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
1087     retval = MPI_SUCCESS;
1088
1089 #ifdef HAVE_TRACING
1090     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1091     (*request)->send = 1;
1092 #endif
1093   }
1094
1095   smpi_bench_begin();
1096   if (retval != MPI_SUCCESS && request)
1097     *request = MPI_REQUEST_NULL;
1098   return retval;
1099 }
1100
1101 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype,
1102                 int dst, int tag, MPI_Comm comm, MPI_Request* request)
1103 {
1104   int retval = 0;
1105
1106   smpi_bench_end();
1107   if (request == NULL) {
1108     retval = MPI_ERR_ARG;
1109   } else if (comm == MPI_COMM_NULL) {
1110     retval = MPI_ERR_COMM;
1111   } else if (dst == MPI_PROC_NULL) {
1112     *request = MPI_REQUEST_NULL;
1113     retval = MPI_SUCCESS;
1114   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1115     retval = MPI_ERR_RANK;
1116   } else if (count < 0) {
1117     retval = MPI_ERR_COUNT;
1118   } else if (buf==NULL && count > 0) {
1119     retval = MPI_ERR_COUNT;
1120   } else if (!is_datatype_valid(datatype)) {
1121       retval = MPI_ERR_TYPE;
1122   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1123     retval = MPI_ERR_TAG;
1124   } else {
1125
1126 #ifdef HAVE_TRACING
1127     int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1128     int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1129     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1130     extra->type = TRACING_ISSEND;
1131     extra->send_size = count;
1132     extra->src = rank;
1133     extra->dst = dst_traced;
1134     extra->datatype1 = encode_datatype(datatype);
1135     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1136     TRACE_smpi_send(rank, rank, dst_traced, count*smpi_datatype_size(datatype));
1137 #endif
1138
1139     *request = smpi_mpi_issend(buf, count, datatype, dst, tag, comm);
1140     retval = MPI_SUCCESS;
1141
1142 #ifdef HAVE_TRACING
1143     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1144     (*request)->send = 1;
1145 #endif
1146   }
1147
1148   smpi_bench_begin();
1149   if (retval != MPI_SUCCESS && request)
1150     *request = MPI_REQUEST_NULL;
1151   return retval;
1152 }
1153
1154 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag,
1155              MPI_Comm comm, MPI_Status * status)
1156 {
1157   int retval = 0;
1158
1159   smpi_bench_end();
1160   if (comm == MPI_COMM_NULL) {
1161     retval = MPI_ERR_COMM;
1162   } else if (src == MPI_PROC_NULL) {
1163     smpi_empty_status(status);
1164     status->MPI_SOURCE = MPI_PROC_NULL;
1165     retval = MPI_SUCCESS;
1166   } else if (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0)){
1167     retval = MPI_ERR_RANK;
1168   } else if (count < 0) {
1169     retval = MPI_ERR_COUNT;
1170   } else if (buf==NULL && count > 0) {
1171     retval = MPI_ERR_COUNT;
1172   } else if (!is_datatype_valid(datatype)) {
1173       retval = MPI_ERR_TYPE;
1174   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1175     retval = MPI_ERR_TAG;
1176   } else {
1177 #ifdef HAVE_TRACING
1178   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1179   int src_traced = smpi_group_index(smpi_comm_group(comm), src);
1180   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1181   extra->type = TRACING_RECV;
1182   extra->send_size = count;
1183   extra->src = src_traced;
1184   extra->dst = rank;
1185   extra->datatype1 = encode_datatype(datatype);
1186   TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra);
1187 #endif
1188
1189     smpi_mpi_recv(buf, count, datatype, src, tag, comm, status);
1190     retval = MPI_SUCCESS;
1191
1192 #ifdef HAVE_TRACING
1193   //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1194   if(status!=MPI_STATUS_IGNORE){
1195     src_traced = smpi_group_index(smpi_comm_group(comm), status->MPI_SOURCE);
1196     TRACE_smpi_recv(rank, src_traced, rank);
1197   }
1198   TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
1199 #endif
1200   }
1201
1202   smpi_bench_begin();
1203   return retval;
1204 }
1205
1206 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag,
1207              MPI_Comm comm)
1208 {
1209   int retval = 0;
1210
1211   smpi_bench_end();
1212
1213   if (comm == MPI_COMM_NULL) {
1214     retval = MPI_ERR_COMM;
1215   } else if (dst == MPI_PROC_NULL) {
1216     retval = MPI_SUCCESS;
1217   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1218     retval = MPI_ERR_RANK;
1219   } else if (count < 0) {
1220     retval = MPI_ERR_COUNT;
1221   } else if (buf==NULL && count > 0) {
1222     retval = MPI_ERR_COUNT;
1223   } else if (!is_datatype_valid(datatype)) {
1224       retval = MPI_ERR_TYPE;
1225   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1226     retval = MPI_ERR_TAG;
1227   } else {
1228
1229 #ifdef HAVE_TRACING
1230   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1231   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1232   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1233   extra->type = TRACING_SEND;
1234   extra->send_size = count;
1235   extra->src = rank;
1236   extra->dst = dst_traced;
1237   extra->datatype1 = encode_datatype(datatype);
1238   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1239   TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1240 #endif
1241
1242     smpi_mpi_send(buf, count, datatype, dst, tag, comm);
1243     retval = MPI_SUCCESS;
1244
1245 #ifdef HAVE_TRACING
1246   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1247 #endif
1248   }
1249
1250   smpi_bench_begin();
1251   return retval;
1252 }
1253
1254
1255
1256 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
1257   int retval = 0;
1258
1259    smpi_bench_end();
1260
1261    if (comm == MPI_COMM_NULL) {
1262      retval = MPI_ERR_COMM;
1263    } else if (dst == MPI_PROC_NULL) {
1264      retval = MPI_SUCCESS;
1265    } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1266      retval = MPI_ERR_RANK;
1267    } else if (count < 0) {
1268      retval = MPI_ERR_COUNT;
1269    } else if (buf==NULL && count > 0) {
1270      retval = MPI_ERR_COUNT;
1271    } else if (!is_datatype_valid(datatype)){
1272      retval = MPI_ERR_TYPE;
1273    } else if(tag<0 && tag !=  MPI_ANY_TAG){
1274      retval = MPI_ERR_TAG;
1275    } else {
1276
1277  #ifdef HAVE_TRACING
1278    int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1279    int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1280    instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1281    extra->type = TRACING_SSEND;
1282    extra->send_size = count;
1283    extra->src = rank;
1284    extra->dst = dst_traced;
1285    extra->datatype1 = encode_datatype(datatype);
1286    TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);   TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1287  #endif
1288
1289      smpi_mpi_ssend(buf, count, datatype, dst, tag, comm);
1290      retval = MPI_SUCCESS;
1291
1292  #ifdef HAVE_TRACING
1293    TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1294  #endif
1295    }
1296
1297    smpi_bench_begin();
1298    return retval;}
1299
1300
1301 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1302                  int dst, int sendtag, void *recvbuf, int recvcount,
1303                  MPI_Datatype recvtype, int src, int recvtag,
1304                  MPI_Comm comm, MPI_Status * status)
1305 {
1306   int retval = 0;
1307
1308   smpi_bench_end();
1309
1310   if (comm == MPI_COMM_NULL) {
1311     retval = MPI_ERR_COMM;
1312   } else if (!is_datatype_valid(sendtype)
1313              || !is_datatype_valid(recvtype)) {
1314     retval = MPI_ERR_TYPE;
1315   } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1316       smpi_empty_status(status);
1317       status->MPI_SOURCE = MPI_PROC_NULL;
1318       retval = MPI_SUCCESS;
1319   }else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0 ||
1320       (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0))){
1321     retval = MPI_ERR_RANK;
1322   } else if (sendcount < 0 || recvcount<0) {
1323       retval = MPI_ERR_COUNT;
1324   } else if ((sendbuf==NULL && sendcount > 0)||(recvbuf==NULL && recvcount>0)) {
1325     retval = MPI_ERR_COUNT;
1326   } else if((sendtag<0 && sendtag !=  MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1327     retval = MPI_ERR_TAG;
1328   } else {
1329
1330 #ifdef HAVE_TRACING
1331   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1332   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1333   int src_traced = smpi_group_index(smpi_comm_group(comm), src);
1334   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1335   extra->type = TRACING_SENDRECV;
1336   extra->send_size = sendcount;
1337   extra->recv_size = recvcount;
1338   extra->src = src_traced;
1339   extra->dst = dst_traced;
1340   extra->datatype1 = encode_datatype(sendtype);
1341   extra->datatype2 = encode_datatype(recvtype);
1342
1343   TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1344   TRACE_smpi_send(rank, rank, dst_traced,sendcount*smpi_datatype_size(sendtype));
1345 #endif
1346
1347
1348     smpi_mpi_sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf,
1349                       recvcount, recvtype, src, recvtag, comm, status);
1350     retval = MPI_SUCCESS;
1351
1352 #ifdef HAVE_TRACING
1353   TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1354   TRACE_smpi_recv(rank, src_traced, rank);
1355 #endif
1356
1357   }
1358
1359   smpi_bench_begin();
1360   return retval;
1361 }
1362
1363 int PMPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,
1364                          int dst, int sendtag, int src, int recvtag,
1365                          MPI_Comm comm, MPI_Status * status)
1366 {
1367   //TODO: suboptimal implementation
1368   void *recvbuf;
1369   int retval = 0;
1370   if (!is_datatype_valid(datatype)) {
1371       retval = MPI_ERR_TYPE;
1372   } else if (count < 0) {
1373       retval = MPI_ERR_COUNT;
1374   } else {
1375     int size = smpi_datatype_get_extent(datatype) * count;
1376     recvbuf = xbt_new0(char, size);
1377     retval =
1378         MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count,
1379                      datatype, src, recvtag, comm, status);
1380     if(retval==MPI_SUCCESS){
1381         smpi_datatype_copy(recvbuf, count, datatype, buf, count, datatype);
1382     }
1383     xbt_free(recvbuf);
1384
1385   }
1386   return retval;
1387 }
1388
1389 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1390 {
1391   int retval = 0;
1392   smpi_bench_end();
1393   if (request == NULL || flag == NULL) {
1394     retval = MPI_ERR_ARG;
1395   } else if (*request == MPI_REQUEST_NULL) {
1396     *flag= TRUE;
1397     smpi_empty_status(status);
1398     retval = MPI_ERR_REQUEST;
1399   } else {
1400 #ifdef HAVE_TRACING
1401     int rank = request && (*request)->comm != MPI_COMM_NULL
1402       ? smpi_process_index()
1403       : -1;
1404
1405     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1406     extra->type = TRACING_TEST;
1407     TRACE_smpi_testing_in(rank, extra);
1408 #endif
1409     *flag = smpi_mpi_test(request, status);
1410 #ifdef HAVE_TRACING
1411     TRACE_smpi_testing_out(rank);
1412 #endif
1413     retval = MPI_SUCCESS;
1414   }
1415   smpi_bench_begin();
1416   return retval;
1417 }
1418
1419 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag,
1420                 MPI_Status * status)
1421 {
1422   int retval = 0;
1423
1424   smpi_bench_end();
1425   if (index == NULL || flag == NULL) {
1426     retval = MPI_ERR_ARG;
1427   } else {
1428     *flag = smpi_mpi_testany(count, requests, index, status);
1429     retval = MPI_SUCCESS;
1430   }
1431   smpi_bench_begin();
1432   return retval;
1433 }
1434
1435 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1436 {
1437   int retval = 0;
1438
1439   smpi_bench_end();
1440   if (flag == NULL) {
1441     retval = MPI_ERR_ARG;
1442   } else {
1443     *flag = smpi_mpi_testall(count, requests, statuses);
1444     retval = MPI_SUCCESS;
1445   }
1446   smpi_bench_begin();
1447   return retval;
1448 }
1449
1450 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1451   int retval = 0;
1452   smpi_bench_end();
1453
1454   if (status == NULL) {
1455     retval = MPI_ERR_ARG;
1456   } else if (comm == MPI_COMM_NULL) {
1457     retval = MPI_ERR_COMM;
1458   } else if (source == MPI_PROC_NULL) {
1459     smpi_empty_status(status);
1460     status->MPI_SOURCE = MPI_PROC_NULL;
1461     retval = MPI_SUCCESS;
1462   } else {
1463     smpi_mpi_probe(source, tag, comm, status);
1464     retval = MPI_SUCCESS;
1465   }
1466   smpi_bench_begin();
1467   return retval;
1468 }
1469
1470
1471 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1472   int retval = 0;
1473   smpi_bench_end();
1474
1475   if (flag == NULL) {
1476     retval = MPI_ERR_ARG;
1477   } else if (status == NULL) {
1478     retval = MPI_ERR_ARG;
1479   } else if (comm == MPI_COMM_NULL) {
1480     retval = MPI_ERR_COMM;
1481   } else if (source == MPI_PROC_NULL) {
1482     *flag=TRUE;
1483     smpi_empty_status(status);
1484     status->MPI_SOURCE = MPI_PROC_NULL;
1485     retval = MPI_SUCCESS;
1486   } else {
1487     smpi_mpi_iprobe(source, tag, comm, flag, status);
1488     retval = MPI_SUCCESS;
1489   }
1490   smpi_bench_begin();
1491   return retval;
1492 }
1493
1494 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1495 {
1496   int retval = 0;
1497
1498   smpi_bench_end();
1499
1500   smpi_empty_status(status);
1501
1502   if (request == NULL) {
1503     retval = MPI_ERR_ARG;
1504   } else if (*request == MPI_REQUEST_NULL) {
1505     retval = MPI_ERR_REQUEST;
1506   } else {
1507
1508 #ifdef HAVE_TRACING
1509     int rank = request && (*request)->comm != MPI_COMM_NULL
1510       ? smpi_process_index()
1511       : -1;
1512
1513     int src_traced = (*request)->src;
1514     int dst_traced = (*request)->dst;
1515     MPI_Comm comm = (*request)->comm;
1516     int is_wait_for_receive = (*request)->recv;
1517     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1518     extra->type = TRACING_WAIT;
1519     TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1520 #endif
1521
1522     smpi_mpi_wait(request, status);
1523     retval = MPI_SUCCESS;
1524
1525 #ifdef HAVE_TRACING
1526     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1527     TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1528     if (is_wait_for_receive) {
1529       if(src_traced==MPI_ANY_SOURCE)
1530         src_traced = (status!=MPI_STATUS_IGNORE) ?
1531           smpi_group_rank(smpi_comm_group(comm), status->MPI_SOURCE) :
1532           src_traced;
1533       TRACE_smpi_recv(rank, src_traced, dst_traced);
1534     }
1535 #endif
1536
1537   }
1538
1539   smpi_bench_begin();
1540   return retval;
1541 }
1542
1543 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1544 {
1545   if (index == NULL)
1546     return MPI_ERR_ARG;
1547
1548   smpi_bench_end();
1549 #ifdef HAVE_TRACING
1550   //save requests information for tracing
1551   int i;
1552   int *srcs = xbt_new0(int, count);
1553   int *dsts = xbt_new0(int, count);
1554   int *recvs = xbt_new0(int, count);
1555   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1556
1557   for (i = 0; i < count; i++) {
1558     MPI_Request req = requests[i];      //already received requests are no longer valid
1559     if (req) {
1560       srcs[i] = req->src;
1561       dsts[i] = req->dst;
1562       recvs[i] = req->recv;
1563       comms[i] = req->comm;
1564     }
1565   }
1566   int rank_traced = smpi_process_index();
1567   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1568   extra->type = TRACING_WAITANY;
1569   extra->send_size=count;
1570   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1571
1572 #endif
1573   *index = smpi_mpi_waitany(count, requests, status);
1574 #ifdef HAVE_TRACING
1575   if(*index!=MPI_UNDEFINED){
1576     int src_traced = srcs[*index];
1577     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1578     int dst_traced = dsts[*index];
1579     int is_wait_for_receive = recvs[*index];
1580     if (is_wait_for_receive) {
1581       if(srcs[*index]==MPI_ANY_SOURCE)
1582         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1583                       smpi_group_rank(smpi_comm_group(comms[*index]), status->MPI_SOURCE) :
1584                       srcs[*index];
1585       TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1586     }
1587     TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1588     xbt_free(srcs);
1589     xbt_free(dsts);
1590     xbt_free(recvs);
1591     xbt_free(comms);
1592
1593   }
1594 #endif
1595   smpi_bench_begin();
1596   return MPI_SUCCESS;
1597 }
1598
1599 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1600 {
1601
1602   smpi_bench_end();
1603 #ifdef HAVE_TRACING
1604   //save information from requests
1605   int i;
1606   int *srcs = xbt_new0(int, count);
1607   int *dsts = xbt_new0(int, count);
1608   int *recvs = xbt_new0(int, count);
1609   int *valid = xbt_new0(int, count);
1610   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1611
1612   //int valid_count = 0;
1613   for (i = 0; i < count; i++) {
1614     MPI_Request req = requests[i];
1615     if(req!=MPI_REQUEST_NULL){
1616       srcs[i] = req->src;
1617       dsts[i] = req->dst;
1618       recvs[i] = req->recv;
1619       comms[i] = req->comm;
1620       valid[i]=1;;
1621     }else{
1622       valid[i]=0;
1623     }
1624   }
1625   int rank_traced = smpi_process_index();
1626   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1627   extra->type = TRACING_WAITALL;
1628   extra->send_size=count;
1629   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1630 #endif
1631   int retval = smpi_mpi_waitall(count, requests, status);
1632 #ifdef HAVE_TRACING
1633   for (i = 0; i < count; i++) {
1634     if(valid[i]){
1635     //int src_traced = srcs[*index];
1636     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1637       int src_traced = srcs[i];
1638       int dst_traced = dsts[i];
1639       int is_wait_for_receive = recvs[i];
1640       if (is_wait_for_receive) {
1641         if(src_traced==MPI_ANY_SOURCE)
1642         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1643                           smpi_group_rank(smpi_comm_group(comms[i]), status[i].MPI_SOURCE) :
1644                           srcs[i];
1645         TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1646       }
1647     }
1648   }
1649   TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1650   xbt_free(srcs);
1651   xbt_free(dsts);
1652   xbt_free(recvs);
1653   xbt_free(valid);
1654   xbt_free(comms);
1655
1656 #endif
1657   smpi_bench_begin();
1658   return retval;
1659 }
1660
1661 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount,
1662                  int *indices, MPI_Status status[])
1663 {
1664   int retval = 0;
1665
1666   smpi_bench_end();
1667   if (outcount == NULL) {
1668     retval = MPI_ERR_ARG;
1669   } else {
1670     *outcount = smpi_mpi_waitsome(incount, requests, indices, status);
1671     retval = MPI_SUCCESS;
1672   }
1673   smpi_bench_begin();
1674   return retval;
1675 }
1676
1677 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount,
1678                  int* indices, MPI_Status status[])
1679 {
1680   int retval = 0;
1681
1682    smpi_bench_end();
1683    if (outcount == NULL) {
1684      retval = MPI_ERR_ARG;
1685    } else {
1686      *outcount = smpi_mpi_testsome(incount, requests, indices, status);
1687      retval = MPI_SUCCESS;
1688    }
1689    smpi_bench_begin();
1690    return retval;
1691 }
1692
1693
1694 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1695 {
1696   int retval = 0;
1697
1698   smpi_bench_end();
1699
1700   if (comm == MPI_COMM_NULL) {
1701     retval = MPI_ERR_COMM;
1702   } else {
1703 #ifdef HAVE_TRACING
1704   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1705   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1706
1707   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1708   extra->type = TRACING_BCAST;
1709   extra->send_size = count;
1710   extra->root = root_traced;
1711   extra->datatype1 = encode_datatype(datatype);
1712   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1713
1714 #endif
1715     mpi_coll_bcast_fun(buf, count, datatype, root, comm);
1716     retval = MPI_SUCCESS;
1717 #ifdef HAVE_TRACING
1718   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1719 #endif
1720   }
1721
1722   smpi_bench_begin();
1723   return retval;
1724 }
1725
1726 int PMPI_Barrier(MPI_Comm comm)
1727 {
1728   int retval = 0;
1729
1730   smpi_bench_end();
1731
1732   if (comm == MPI_COMM_NULL) {
1733     retval = MPI_ERR_COMM;
1734   } else {
1735 #ifdef HAVE_TRACING
1736   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1737   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1738   extra->type = TRACING_BARRIER;
1739   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1740 #endif
1741     mpi_coll_barrier_fun(comm);
1742     retval = MPI_SUCCESS;
1743 #ifdef HAVE_TRACING
1744   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1745 #endif
1746   }
1747
1748   smpi_bench_begin();
1749   return retval;
1750 }
1751
1752 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1753                void *recvbuf, int recvcount, MPI_Datatype recvtype,
1754                int root, MPI_Comm comm)
1755 {
1756   int retval = 0;
1757
1758   smpi_bench_end();
1759
1760   if (comm == MPI_COMM_NULL) {
1761     retval = MPI_ERR_COMM;
1762   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1763             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1764     retval = MPI_ERR_TYPE;
1765   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1766             ((smpi_comm_rank(comm) == root) && (recvcount <0))){
1767     retval = MPI_ERR_COUNT;
1768   } else {
1769
1770     char* sendtmpbuf = (char*) sendbuf;
1771     int sendtmpcount = sendcount;
1772     MPI_Datatype sendtmptype = sendtype;
1773     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1774       sendtmpcount=0;
1775       sendtmptype=recvtype;
1776     }
1777 #ifdef HAVE_TRACING
1778   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1779   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1780   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1781   extra->type = TRACING_GATHER;
1782   extra->send_size = sendtmpcount;
1783   extra->recv_size = recvcount;
1784   extra->root = root_traced;
1785   extra->datatype1 = encode_datatype(sendtmptype);
1786   extra->datatype2 = encode_datatype(recvtype);
1787
1788   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1789 #endif
1790     mpi_coll_gather_fun(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount,
1791                     recvtype, root, comm);
1792
1793
1794     retval = MPI_SUCCESS;
1795 #ifdef HAVE_TRACING
1796   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1797 #endif
1798   }
1799
1800   smpi_bench_begin();
1801   return retval;
1802 }
1803
1804 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1805                 void *recvbuf, int *recvcounts, int *displs,
1806                 MPI_Datatype recvtype, int root, MPI_Comm comm)
1807 {
1808   int retval = 0;
1809
1810   smpi_bench_end();
1811
1812   if (comm == MPI_COMM_NULL) {
1813     retval = MPI_ERR_COMM;
1814   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1815             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1816     retval = MPI_ERR_TYPE;
1817   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1818     retval = MPI_ERR_COUNT;
1819   } else if (recvcounts == NULL || displs == NULL) {
1820     retval = MPI_ERR_ARG;
1821   } else {
1822     char* sendtmpbuf = (char*) sendbuf;
1823     int sendtmpcount = sendcount;
1824     MPI_Datatype sendtmptype = sendtype;
1825     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1826       sendtmpcount=0;
1827       sendtmptype=recvtype;
1828     }
1829
1830 #ifdef HAVE_TRACING
1831   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1832   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1833   int i=0;
1834   int size = smpi_comm_size(comm);
1835   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1836   extra->type = TRACING_GATHERV;
1837   extra->send_size = sendtmpcount;
1838   extra->recvcounts= xbt_malloc(size*sizeof(int));
1839   for(i=0; i< size; i++)//copy data to avoid bad free
1840     extra->recvcounts[i] = recvcounts[i];
1841   extra->num_processes = size;
1842   extra->root = root_traced;
1843   extra->datatype1 = encode_datatype(sendtmptype);
1844   extra->datatype2 = encode_datatype(recvtype);
1845
1846   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1847 #endif
1848     smpi_mpi_gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts,
1849                      displs, recvtype, root, comm);
1850     retval = MPI_SUCCESS;
1851 #ifdef HAVE_TRACING
1852   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1853 #endif
1854   }
1855
1856   smpi_bench_begin();
1857   return retval;
1858 }
1859
1860 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1861                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
1862                   MPI_Comm comm)
1863 {
1864   int retval = 0;
1865
1866   smpi_bench_end();
1867
1868   if (comm == MPI_COMM_NULL) {
1869     retval = MPI_ERR_COMM;
1870   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1871             (recvtype == MPI_DATATYPE_NULL)){
1872     retval = MPI_ERR_TYPE;
1873   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1874             (recvcount <0)){
1875     retval = MPI_ERR_COUNT;
1876   } else {
1877     if(sendbuf == MPI_IN_PLACE) {
1878       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*recvcount*smpi_comm_rank(comm);
1879       sendcount=recvcount;
1880       sendtype=recvtype;
1881     }
1882 #ifdef HAVE_TRACING
1883   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1884   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1885   extra->type = TRACING_ALLGATHER;
1886   extra->send_size = sendcount;
1887   extra->recv_size = recvcount;
1888   extra->datatype1 = encode_datatype(sendtype);
1889   extra->datatype2 = encode_datatype(recvtype);
1890
1891   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1892 #endif
1893     mpi_coll_allgather_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1894                            recvtype, comm);
1895     retval = MPI_SUCCESS;
1896
1897 #ifdef HAVE_TRACING
1898   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1899 #endif
1900   }
1901   smpi_bench_begin();
1902   return retval;
1903 }
1904
1905 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1906                    void *recvbuf, int *recvcounts, int *displs,
1907                    MPI_Datatype recvtype, MPI_Comm comm)
1908 {
1909   int retval = 0;
1910
1911   smpi_bench_end();
1912
1913   if (comm == MPI_COMM_NULL) {
1914     retval = MPI_ERR_COMM;
1915   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1916             (recvtype == MPI_DATATYPE_NULL)){
1917     retval = MPI_ERR_TYPE;
1918   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1919     retval = MPI_ERR_COUNT;
1920   } else if (recvcounts == NULL || displs == NULL) {
1921     retval = MPI_ERR_ARG;
1922   } else {
1923
1924     if(sendbuf == MPI_IN_PLACE) {
1925       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*displs[smpi_comm_rank(comm)];
1926       sendcount=recvcounts[smpi_comm_rank(comm)];
1927       sendtype=recvtype;
1928     }
1929 #ifdef HAVE_TRACING
1930   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1931   int i=0;
1932   int size = smpi_comm_size(comm);
1933   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1934   extra->type = TRACING_ALLGATHERV;
1935   extra->send_size = sendcount;
1936   extra->recvcounts= xbt_malloc(size*sizeof(int));
1937   for(i=0; i< size; i++)//copy data to avoid bad free
1938     extra->recvcounts[i] = recvcounts[i];
1939   extra->num_processes = size;
1940   extra->datatype1 = encode_datatype(sendtype);
1941   extra->datatype2 = encode_datatype(recvtype);
1942
1943   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
1944 #endif
1945     mpi_coll_allgatherv_fun(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
1946                         displs, recvtype, comm);
1947     retval = MPI_SUCCESS;
1948 #ifdef HAVE_TRACING
1949   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1950 #endif
1951   }
1952
1953   smpi_bench_begin();
1954   return retval;
1955 }
1956
1957 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1958                 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1959                 int root, MPI_Comm comm)
1960 {
1961   int retval = 0;
1962
1963   smpi_bench_end();
1964
1965   if (comm == MPI_COMM_NULL) {
1966     retval = MPI_ERR_COMM;
1967   } else if (((smpi_comm_rank(comm)==root) && (sendtype == MPI_DATATYPE_NULL))
1968              || ((recvbuf !=MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
1969     retval = MPI_ERR_TYPE;
1970   } else {
1971
1972     if (recvbuf == MPI_IN_PLACE) {
1973         recvtype=sendtype;
1974         recvcount=sendcount;
1975     }
1976 #ifdef HAVE_TRACING
1977   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1978   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1979   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1980   extra->type = TRACING_SCATTER;
1981   extra->send_size = sendcount;
1982   extra->recv_size= recvcount;
1983   extra->root = root_traced;
1984   extra->datatype1 = encode_datatype(sendtype);
1985   extra->datatype2 = encode_datatype(recvtype);
1986
1987   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1988 #endif
1989     mpi_coll_scatter_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1990                      recvtype, root, comm);
1991     retval = MPI_SUCCESS;
1992 #ifdef HAVE_TRACING
1993   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1994 #endif
1995   }
1996
1997   smpi_bench_begin();
1998   return retval;
1999 }
2000
2001 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
2002                  MPI_Datatype sendtype, void *recvbuf, int recvcount,
2003                  MPI_Datatype recvtype, int root, MPI_Comm comm)
2004 {
2005   int retval = 0;
2006
2007   smpi_bench_end();
2008
2009   if (comm == MPI_COMM_NULL) {
2010     retval = MPI_ERR_COMM;
2011   } else if (sendcounts == NULL || displs == NULL) {
2012     retval = MPI_ERR_ARG;
2013   } else if (((smpi_comm_rank(comm)==root) && (sendtype == MPI_DATATYPE_NULL))
2014              || ((recvbuf !=MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
2015     retval = MPI_ERR_TYPE;
2016   } else {
2017     if (recvbuf == MPI_IN_PLACE) {
2018         recvtype=sendtype;
2019         recvcount=sendcounts[smpi_comm_rank(comm)];
2020     }
2021 #ifdef HAVE_TRACING
2022   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2023   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2024   int i=0;
2025   int size = smpi_comm_size(comm);
2026   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2027   extra->type = TRACING_SCATTERV;
2028   extra->recv_size = recvcount;
2029   extra->sendcounts= xbt_malloc(size*sizeof(int));
2030   for(i=0; i< size; i++)//copy data to avoid bad free
2031     extra->sendcounts[i] = sendcounts[i];
2032   extra->num_processes = size;
2033   extra->root = root_traced;
2034   extra->datatype1 = encode_datatype(sendtype);
2035   extra->datatype2 = encode_datatype(recvtype);
2036
2037   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2038
2039 #endif
2040     smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf,
2041                       recvcount, recvtype, root, comm);
2042     retval = MPI_SUCCESS;
2043 #ifdef HAVE_TRACING
2044   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2045 #endif
2046   }
2047
2048   smpi_bench_begin();
2049   return retval;
2050 }
2051
2052 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
2053                MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
2054 {
2055   int retval = 0;
2056
2057   smpi_bench_end();
2058
2059   if (comm == MPI_COMM_NULL) {
2060     retval = MPI_ERR_COMM;
2061   } else if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2062     retval = MPI_ERR_ARG;
2063   } else {
2064 #ifdef HAVE_TRACING
2065   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2066   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2067   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2068   extra->type = TRACING_REDUCE;
2069   extra->send_size = count;
2070   extra->datatype1 = encode_datatype(datatype);
2071   extra->root = root_traced;
2072
2073   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2074 #endif
2075     mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, root, comm);
2076
2077     retval = MPI_SUCCESS;
2078 #ifdef HAVE_TRACING
2079   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2080 #endif
2081   }
2082
2083   smpi_bench_begin();
2084   return retval;
2085 }
2086
2087 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count,
2088     MPI_Datatype datatype, MPI_Op op){
2089   int retval = 0;
2090
2091     smpi_bench_end();
2092     if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2093       retval = MPI_ERR_ARG;
2094     } else {
2095       smpi_op_apply(op, inbuf, inoutbuf, &count, &datatype);
2096       retval=MPI_SUCCESS;
2097     }
2098     smpi_bench_begin();
2099     return retval;
2100 }
2101
2102 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
2103                   MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2104 {
2105   int retval = 0;
2106
2107   smpi_bench_end();
2108
2109   if (comm == MPI_COMM_NULL) {
2110     retval = MPI_ERR_COMM;
2111   } else if (!is_datatype_valid(datatype)) {
2112     retval = MPI_ERR_TYPE;
2113   } else if (op == MPI_OP_NULL) {
2114     retval = MPI_ERR_OP;
2115   } else {
2116
2117     char* sendtmpbuf = (char*) sendbuf;
2118     if( sendbuf == MPI_IN_PLACE ) {
2119       sendtmpbuf = (char *)xbt_malloc(count*smpi_datatype_get_extent(datatype));
2120       smpi_datatype_copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
2121     }
2122 #ifdef HAVE_TRACING
2123   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2124   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2125   extra->type = TRACING_ALLREDUCE;
2126   extra->send_size = count;
2127   extra->datatype1 = encode_datatype(datatype);
2128
2129   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2130 #endif
2131     mpi_coll_allreduce_fun(sendtmpbuf, recvbuf, count, datatype, op, comm);
2132
2133     if( sendbuf == MPI_IN_PLACE ) {
2134       xbt_free(sendtmpbuf);
2135     }
2136
2137     retval = MPI_SUCCESS;
2138 #ifdef HAVE_TRACING
2139   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2140 #endif
2141   }
2142
2143   smpi_bench_begin();
2144   return retval;
2145 }
2146
2147 int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
2148              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2149 {
2150   int retval = 0;
2151
2152   smpi_bench_end();
2153
2154   if (comm == MPI_COMM_NULL) {
2155     retval = MPI_ERR_COMM;
2156   } else if (!is_datatype_valid(datatype)) {
2157     retval = MPI_ERR_TYPE;
2158   } else if (op == MPI_OP_NULL) {
2159     retval = MPI_ERR_OP;
2160   } else {
2161 #ifdef HAVE_TRACING
2162   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2163   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2164   extra->type = TRACING_SCAN;
2165   extra->send_size = count;
2166   extra->datatype1 = encode_datatype(datatype);
2167
2168   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2169 #endif
2170     smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
2171     retval = MPI_SUCCESS;
2172 #ifdef HAVE_TRACING
2173   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2174 #endif
2175   }
2176
2177   smpi_bench_begin();
2178   return retval;
2179 }
2180
2181 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
2182                 MPI_Op op, MPI_Comm comm){
2183   int retval = 0;
2184
2185   smpi_bench_end();
2186
2187   if (comm == MPI_COMM_NULL) {
2188     retval = MPI_ERR_COMM;
2189   } else if (!is_datatype_valid(datatype)) {
2190     retval = MPI_ERR_TYPE;
2191   } else if (op == MPI_OP_NULL) {
2192     retval = MPI_ERR_OP;
2193   } else {
2194 #ifdef HAVE_TRACING
2195   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2196   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2197   extra->type = TRACING_EXSCAN;
2198   extra->send_size = count;
2199   extra->datatype1 = encode_datatype(datatype);
2200
2201   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2202 #endif
2203     smpi_mpi_exscan(sendbuf, recvbuf, count, datatype, op, comm);
2204     retval = MPI_SUCCESS;
2205 #ifdef HAVE_TRACING
2206   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2207 #endif
2208   }
2209
2210   smpi_bench_begin();
2211   return retval;
2212 }
2213
2214 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
2215                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2216 {
2217   int retval = 0;
2218   smpi_bench_end();
2219
2220   if (comm == MPI_COMM_NULL) {
2221     retval = MPI_ERR_COMM;
2222   } else if (!is_datatype_valid(datatype)) {
2223     retval = MPI_ERR_TYPE;
2224   } else if (op == MPI_OP_NULL) {
2225     retval = MPI_ERR_OP;
2226   } else if (recvcounts == NULL) {
2227     retval = MPI_ERR_ARG;
2228   } else {
2229 #ifdef HAVE_TRACING
2230   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2231   int i=0;
2232   int size = smpi_comm_size(comm);
2233   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2234   extra->type = TRACING_REDUCE_SCATTER;
2235   extra->send_size = 0;
2236   extra->recvcounts= xbt_malloc(size*sizeof(int));
2237   for(i=0; i< size; i++)//copy data to avoid bad free
2238     extra->recvcounts[i] = recvcounts[i];
2239   extra->num_processes = size;
2240   extra->datatype1 = encode_datatype(datatype);
2241
2242   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2243 #endif
2244     void* sendtmpbuf=sendbuf;
2245     if(sendbuf==MPI_IN_PLACE){
2246       sendtmpbuf=recvbuf;
2247     }
2248
2249     mpi_coll_reduce_scatter_fun(sendtmpbuf, recvbuf, recvcounts,
2250                        datatype,  op, comm);
2251     retval = MPI_SUCCESS;
2252 #ifdef HAVE_TRACING
2253   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2254 #endif
2255   }
2256
2257   smpi_bench_begin();
2258   return retval;
2259 }
2260
2261 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
2262                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2263 {
2264   int retval,i;
2265   smpi_bench_end();
2266
2267   if (comm == MPI_COMM_NULL) {
2268     retval = MPI_ERR_COMM;
2269   } else if (!is_datatype_valid(datatype)) {
2270     retval = MPI_ERR_TYPE;
2271   } else if (op == MPI_OP_NULL) {
2272     retval = MPI_ERR_OP;
2273   } else if (recvcount < 0) {
2274     retval = MPI_ERR_ARG;
2275   } else {
2276     int count=smpi_comm_size(comm);
2277
2278 #ifdef HAVE_TRACING
2279   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2280   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2281   extra->type = TRACING_REDUCE_SCATTER;
2282   extra->send_size = 0;
2283   extra->recvcounts= xbt_malloc(count*sizeof(int));
2284   for(i=0; i< count; i++)//copy data to avoid bad free
2285     extra->recvcounts[i] = recvcount;
2286   extra->num_processes = count;
2287   extra->datatype1 = encode_datatype(datatype);
2288
2289   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2290 #endif
2291     int* recvcounts=(int*)xbt_malloc(count);
2292     for (i=0; i<count;i++)recvcounts[i]=recvcount;
2293     mpi_coll_reduce_scatter_fun(sendbuf, recvbuf, recvcounts,
2294                        datatype,  op, comm);
2295     xbt_free(recvcounts);
2296     retval = MPI_SUCCESS;
2297 #ifdef HAVE_TRACING
2298   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2299 #endif
2300   }
2301
2302   smpi_bench_begin();
2303   return retval;
2304 }
2305
2306 int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
2307                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
2308                  MPI_Comm comm)
2309 {
2310   int retval = 0;
2311
2312   smpi_bench_end();
2313
2314   if (comm == MPI_COMM_NULL) {
2315     retval = MPI_ERR_COMM;
2316   } else if (sendtype == MPI_DATATYPE_NULL
2317              || recvtype == MPI_DATATYPE_NULL) {
2318     retval = MPI_ERR_TYPE;
2319   } else {
2320 #ifdef HAVE_TRACING
2321   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2322   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2323   extra->type = TRACING_ALLTOALL;
2324   extra->send_size = sendcount;
2325   extra->recv_size = recvcount;
2326   extra->datatype1 = encode_datatype(sendtype);
2327   extra->datatype2 = encode_datatype(recvtype);
2328
2329   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2330 #endif
2331     retval = mpi_coll_alltoall_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
2332 #ifdef HAVE_TRACING
2333   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2334 #endif
2335   }
2336
2337   smpi_bench_begin();
2338   return retval;
2339 }
2340
2341 int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
2342                   MPI_Datatype sendtype, void *recvbuf, int *recvcounts,
2343                   int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2344 {
2345   int retval = 0;
2346
2347   smpi_bench_end();
2348
2349   if (comm == MPI_COMM_NULL) {
2350     retval = MPI_ERR_COMM;
2351   } else if (sendtype == MPI_DATATYPE_NULL
2352              || recvtype == MPI_DATATYPE_NULL) {
2353     retval = MPI_ERR_TYPE;
2354   } else if (sendcounts == NULL || senddisps == NULL || recvcounts == NULL
2355              || recvdisps == NULL) {
2356     retval = MPI_ERR_ARG;
2357   } else {
2358 #ifdef HAVE_TRACING
2359   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2360   int i=0;
2361   int size = smpi_comm_size(comm);
2362   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2363   extra->type = TRACING_ALLTOALLV;
2364   extra->send_size = 0;
2365   extra->recv_size = 0;
2366   extra->recvcounts= xbt_malloc(size*sizeof(int));
2367   extra->sendcounts= xbt_malloc(size*sizeof(int));
2368
2369   for(i=0; i< size; i++){//copy data to avoid bad free
2370     extra->send_size += sendcounts[i];
2371     extra->recv_size += recvcounts[i];
2372
2373     extra->sendcounts[i] = sendcounts[i];
2374     extra->recvcounts[i] = recvcounts[i];
2375   }
2376   extra->num_processes = size;
2377
2378   extra->datatype1 = encode_datatype(sendtype);
2379   extra->datatype2 = encode_datatype(recvtype);
2380
2381   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2382 #endif
2383     retval =
2384         mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps, sendtype,
2385                                   recvbuf, recvcounts, recvdisps, recvtype,
2386                                   comm);
2387 #ifdef HAVE_TRACING
2388   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2389 #endif
2390   }
2391
2392   smpi_bench_begin();
2393   return retval;
2394 }
2395
2396
2397 int PMPI_Get_processor_name(char *name, int *resultlen)
2398 {
2399   int retval = MPI_SUCCESS;
2400
2401   strncpy(name, SIMIX_host_get_name(SIMIX_host_self()),
2402           strlen(SIMIX_host_get_name(SIMIX_host_self())) < MPI_MAX_PROCESSOR_NAME - 1 ?
2403           strlen(SIMIX_host_get_name(SIMIX_host_self())) +1 :
2404           MPI_MAX_PROCESSOR_NAME - 1 );
2405   *resultlen =
2406       strlen(name) >
2407       MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2408
2409   return retval;
2410 }
2411
2412 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2413 {
2414   int retval = MPI_SUCCESS;
2415   size_t size;
2416
2417   if (status == NULL || count == NULL) {
2418     retval = MPI_ERR_ARG;
2419   } else if (!is_datatype_valid(datatype)) {
2420     retval = MPI_ERR_TYPE;
2421   } else {
2422     size = smpi_datatype_size(datatype);
2423     if (size == 0) {
2424       *count = 0;
2425     } else if (status->count % size != 0) {
2426       retval = MPI_UNDEFINED;
2427     } else {
2428       *count = smpi_mpi_get_count(status, datatype);
2429     }
2430   }
2431   return retval;
2432 }
2433
2434 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2435   int retval = 0;
2436
2437   if (old_type == MPI_DATATYPE_NULL) {
2438     retval = MPI_ERR_TYPE;
2439   } else if (count<0){
2440     retval = MPI_ERR_COUNT;
2441   } else {
2442     retval = smpi_datatype_contiguous(count, old_type, new_type, 0);
2443   }
2444   return retval;
2445 }
2446
2447 int PMPI_Type_commit(MPI_Datatype* datatype) {
2448   int retval = 0;
2449
2450   if (datatype == NULL || *datatype == MPI_DATATYPE_NULL) {
2451     retval = MPI_ERR_TYPE;
2452   } else {
2453     smpi_datatype_commit(datatype);
2454     retval = MPI_SUCCESS;
2455   }
2456   return retval;
2457 }
2458
2459
2460 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2461   int retval = 0;
2462
2463   if (old_type == MPI_DATATYPE_NULL) {
2464     retval = MPI_ERR_TYPE;
2465   } else if (count<0 || blocklen<0){
2466     retval = MPI_ERR_COUNT;
2467   } else {
2468     retval = smpi_datatype_vector(count, blocklen, stride, old_type, new_type);
2469   }
2470   return retval;
2471 }
2472
2473 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2474   int retval = 0;
2475
2476   if (old_type == MPI_DATATYPE_NULL) {
2477     retval = MPI_ERR_TYPE;
2478   } else if (count<0 || blocklen<0){
2479     retval = MPI_ERR_COUNT;
2480   } else {
2481     retval = smpi_datatype_hvector(count, blocklen, stride, old_type, new_type);
2482   }
2483   return retval;
2484 }
2485
2486 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2487   return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2488 }
2489
2490 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2491   int retval = 0;
2492
2493   if (old_type == MPI_DATATYPE_NULL) {
2494     retval = MPI_ERR_TYPE;
2495   } else if (count<0){
2496     retval = MPI_ERR_COUNT;
2497   } else {
2498     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2499   }
2500   return retval;
2501 }
2502
2503 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2504   int retval = 0;
2505
2506   if (old_type == MPI_DATATYPE_NULL) {
2507     retval = MPI_ERR_TYPE;
2508   } else if (count<0){
2509     retval = MPI_ERR_COUNT;
2510   } else {
2511     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2512   }
2513   return retval;
2514 }
2515
2516 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2517   int retval,i;
2518
2519   if (old_type == MPI_DATATYPE_NULL) {
2520     retval = MPI_ERR_TYPE;
2521   } else if (count<0){
2522     retval = MPI_ERR_COUNT;
2523   } else {
2524     int* blocklens=(int*)xbt_malloc(blocklength*count);
2525     for (i=0; i<count;i++)blocklens[i]=blocklength;
2526     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2527     xbt_free(blocklens);
2528   }
2529   return retval;
2530 }
2531
2532
2533 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2534   int retval = 0;
2535
2536   if (old_type == MPI_DATATYPE_NULL) {
2537     retval = MPI_ERR_TYPE;
2538   } else if (count<0){
2539     retval = MPI_ERR_COUNT;
2540   } else {
2541     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2542   }
2543   return retval;
2544 }
2545
2546 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2547   return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2548 }
2549
2550 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2551   int retval,i;
2552
2553   if (old_type == MPI_DATATYPE_NULL) {
2554     retval = MPI_ERR_TYPE;
2555   } else if (count<0){
2556     retval = MPI_ERR_COUNT;
2557   } else {
2558     int* blocklens=(int*)xbt_malloc(blocklength*count);
2559     for (i=0; i<count;i++)blocklens[i]=blocklength;
2560     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2561     xbt_free(blocklens);
2562   }
2563   return retval;
2564 }
2565
2566
2567 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2568   int retval = 0;
2569
2570   if (count<0){
2571     retval = MPI_ERR_COUNT;
2572   } else {
2573     retval = smpi_datatype_struct(count, blocklens, indices, old_types, new_type);
2574   }
2575   return retval;
2576 }
2577
2578 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2579   return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2580 }
2581
2582
2583 int PMPI_Error_class(int errorcode, int* errorclass) {
2584   // assume smpi uses only standard mpi error codes
2585   *errorclass=errorcode;
2586   return MPI_SUCCESS;
2587 }
2588
2589
2590 int PMPI_Initialized(int* flag) {
2591    *flag=smpi_process_initialized();
2592    return MPI_SUCCESS;
2593 }
2594
2595 /* The topo part of MPI_COMM_WORLD should always be NULL. When other topologies
2596  * will be implemented, not only should we check if the topology is NULL, but
2597  * we should check if it is the good topology type (so we have to add a
2598  *  MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2599
2600 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2601   int retval = 0;
2602   if (comm_old == MPI_COMM_NULL){
2603     retval =  MPI_ERR_COMM;
2604   } else if (ndims < 0 ||
2605            (ndims > 0 && (dims == NULL || 
2606                           periodic == NULL)) ||
2607            comm_cart == NULL) {
2608     retval = MPI_ERR_ARG;
2609   } else{
2610     retval = smpi_mpi_cart_create(comm_old, ndims, dims, periodic, reorder, comm_cart);
2611   }
2612   return retval;
2613 }
2614
2615 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2616   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2617     return MPI_ERR_TOPOLOGY;
2618   }
2619   if (coords == NULL) {
2620     return MPI_ERR_ARG;
2621   }
2622   return smpi_mpi_cart_rank(comm, coords, rank);
2623 }
2624
2625 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2626   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2627     return MPI_ERR_TOPOLOGY;
2628   }
2629   if (source == NULL || dest == NULL || direction < 0 ) {
2630     return MPI_ERR_ARG;
2631   }
2632   return smpi_mpi_cart_shift(comm, direction, displ, source, dest);
2633 }
2634
2635 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2636   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2637     return MPI_ERR_TOPOLOGY;
2638   }
2639   if (rank < 0 || rank >= smpi_comm_size(comm)) {
2640     return MPI_ERR_RANK;
2641   }
2642   if (maxdims <= 0) {
2643     return MPI_ERR_ARG;
2644   }
2645   if(coords == NULL) {
2646     return MPI_ERR_ARG;
2647   }
2648   return smpi_mpi_cart_coords(comm, rank, maxdims, coords);
2649 }
2650
2651 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2652   if(comm == NULL || smpi_comm_topo(comm) == NULL) {
2653     return MPI_ERR_TOPOLOGY;
2654   }
2655   if(maxdims <= 0 || dims == NULL || periods == NULL || coords == NULL) {
2656     return MPI_ERR_ARG;
2657   }
2658   return smpi_mpi_cart_get(comm, maxdims, dims, periods, coords);
2659 }
2660
2661 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2662   if (comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2663     return MPI_ERR_TOPOLOGY;
2664   }
2665   if (ndims == NULL) {
2666     return MPI_ERR_ARG;
2667   }
2668   return smpi_mpi_cartdim_get(comm, ndims);
2669 }
2670
2671 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2672   if(dims == NULL) {
2673     return MPI_ERR_ARG;
2674   }
2675   if (ndims < 1 || nnodes < 1) {
2676     return MPI_ERR_DIMS;
2677   }
2678
2679   return smpi_mpi_dims_create(nnodes, ndims, dims);
2680 }
2681
2682 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2683   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2684     return MPI_ERR_TOPOLOGY;
2685   }
2686   if (comm_new == NULL) {
2687     return MPI_ERR_ARG;
2688   }
2689   return smpi_mpi_cart_sub(comm, remain_dims, comm_new);
2690 }
2691
2692 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2693     if(oldtype == MPI_DATATYPE_NULL) {
2694         return MPI_ERR_TYPE;
2695     }
2696     int blocks[3] = { 1, 1, 1 };
2697     MPI_Aint disps[3] = { lb, 0, lb+extent };
2698     MPI_Datatype types[3] = { MPI_LB, oldtype, MPI_UB };
2699         
2700     s_smpi_mpi_struct_t* subtype = smpi_datatype_struct_create( blocks,
2701                                                                 disps,
2702                                                                 3,
2703                                                                 types
2704                                                                 );
2705     smpi_datatype_create(newtype,oldtype->size, lb, lb + extent, 1 , subtype, DT_FLAG_VECTOR);
2706
2707     (*newtype)->flags &= ~DT_FLAG_COMMITED;
2708     return MPI_SUCCESS;
2709 }
2710
2711
2712
2713 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2714   int retval = 0;
2715   smpi_bench_end();
2716   if (comm == MPI_COMM_NULL) {
2717     retval= MPI_ERR_COMM;
2718   }else if ((base == NULL && size != 0)
2719             || disp_unit <= 0 || size < 0 ){
2720     retval= MPI_ERR_OTHER;
2721   }else{
2722     *win = smpi_mpi_win_create( base, size, disp_unit, info, comm);
2723     retval = MPI_SUCCESS;
2724   }
2725   smpi_bench_begin();
2726   return retval;
2727 }
2728
2729 int PMPI_Win_free( MPI_Win* win){
2730   int retval = 0;
2731   smpi_bench_end();
2732   if (win == NULL || *win == MPI_WIN_NULL) {
2733     retval = MPI_ERR_WIN;
2734   }else{
2735     retval=smpi_mpi_win_free(win);
2736   }
2737   smpi_bench_begin();
2738   return retval;
2739 }
2740
2741
2742 int PMPI_Win_fence( int assert,  MPI_Win win){
2743   int retval = 0;
2744   smpi_bench_end();
2745   if (win == MPI_WIN_NULL) {
2746     retval = MPI_ERR_WIN;
2747   } else {
2748     retval = smpi_mpi_win_fence(assert, win);
2749   }
2750   smpi_bench_begin();
2751   return retval;
2752 }
2753
2754 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2755               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2756   int retval = 0;
2757   smpi_bench_end();
2758   if (win == MPI_WIN_NULL) {
2759     retval = MPI_ERR_WIN;
2760   } else if (target_rank == MPI_PROC_NULL) {
2761     retval = MPI_SUCCESS;
2762   } else if (target_rank <0){
2763     retval = MPI_ERR_RANK;
2764   } else if (target_disp <0){
2765       retval = MPI_ERR_ARG;
2766   } else if (origin_count < 0 || target_count < 0) {
2767     retval = MPI_ERR_COUNT;
2768   } else if (origin_addr==NULL && origin_count > 0){
2769     retval = MPI_ERR_COUNT;
2770   } else if ((!is_datatype_valid(origin_datatype)) ||
2771             (!is_datatype_valid(target_datatype))) {
2772     retval = MPI_ERR_TYPE;
2773   } else {
2774     retval = smpi_mpi_get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win);
2775   }
2776   smpi_bench_begin();
2777   return retval;
2778 }
2779
2780 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2781               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2782   int retval = 0;
2783   smpi_bench_end();
2784   if (win == MPI_WIN_NULL) {
2785     retval = MPI_ERR_WIN;
2786   } else if (target_rank == MPI_PROC_NULL) {
2787     retval = MPI_SUCCESS;
2788   } else if (target_rank <0){
2789     retval = MPI_ERR_RANK;
2790   } else if (target_disp <0){
2791     retval = MPI_ERR_ARG;
2792   } else if (origin_count < 0 || target_count < 0) {
2793     retval = MPI_ERR_COUNT;
2794   } else if (origin_addr==NULL && origin_count > 0){
2795     retval = MPI_ERR_COUNT;
2796   } else if ((!is_datatype_valid(origin_datatype)) ||
2797             (!is_datatype_valid(target_datatype))) {
2798     retval = MPI_ERR_TYPE;
2799   } else {
2800     retval = smpi_mpi_put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win);
2801   }
2802   smpi_bench_begin();
2803   return retval;
2804 }
2805
2806
2807 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2808               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2809   int retval = 0;
2810   smpi_bench_end();
2811   if (win == MPI_WIN_NULL) {
2812     retval = MPI_ERR_WIN;
2813   } else if (target_rank == MPI_PROC_NULL) {
2814     retval = MPI_SUCCESS;
2815   } else if (target_rank <0){
2816     retval = MPI_ERR_RANK;
2817   } else if (target_disp <0){
2818     retval = MPI_ERR_ARG;
2819   } else if (origin_count < 0 || target_count < 0) {
2820     retval = MPI_ERR_COUNT;
2821   } else if (origin_addr==NULL && origin_count > 0){
2822     retval = MPI_ERR_COUNT;
2823   } else if ((!is_datatype_valid(origin_datatype)) ||
2824             (!is_datatype_valid(target_datatype))) {
2825     retval = MPI_ERR_TYPE;
2826   } else if (op == MPI_OP_NULL) {
2827     retval = MPI_ERR_OP;
2828   } else {
2829     retval = smpi_mpi_accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, op, win);
2830   }
2831   smpi_bench_begin();
2832   return retval;
2833 }
2834
2835
2836 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
2837   void *ptr = xbt_malloc(size);
2838   if(!ptr)
2839     return MPI_ERR_NO_MEM;
2840   else {
2841     *(void **)baseptr = ptr;
2842     return MPI_SUCCESS;
2843   }
2844 }
2845
2846 int PMPI_Free_mem(void *baseptr){
2847   xbt_free(baseptr);
2848   return MPI_SUCCESS;
2849 }
2850
2851
2852
2853 /* The following calls are not yet implemented and will fail at runtime. */
2854 /* Once implemented, please move them above this notice. */
2855
2856 #define NOT_YET_IMPLEMENTED {                                           \
2857     XBT_WARN("Not yet implemented : %s. Please contact the Simgrid team if support is needed", __FUNCTION__); \
2858     return MPI_SUCCESS;                                                 \
2859   }
2860
2861 int PMPI_Type_set_name(MPI_Datatype  datatype, char * name)
2862 {
2863   NOT_YET_IMPLEMENTED
2864 }
2865
2866 int PMPI_Type_get_name(MPI_Datatype  datatype, char * name, int* len)
2867 {
2868   NOT_YET_IMPLEMENTED
2869 }
2870
2871 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
2872   NOT_YET_IMPLEMENTED
2873 }
2874
2875
2876 int PMPI_Cart_map(MPI_Comm comm_old, int ndims, int* dims, int* periods, int* newrank) {
2877   NOT_YET_IMPLEMENTED
2878 }
2879
2880
2881 int PMPI_Graph_create(MPI_Comm comm_old, int nnodes, int* index, int* edges, int reorder, MPI_Comm* comm_graph) {
2882   NOT_YET_IMPLEMENTED
2883 }
2884
2885 int PMPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int* index, int* edges) {
2886   NOT_YET_IMPLEMENTED
2887 }
2888
2889 int PMPI_Graph_map(MPI_Comm comm_old, int nnodes, int* index, int* edges, int* newrank) {
2890   NOT_YET_IMPLEMENTED
2891 }
2892
2893 int PMPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int* neighbors) {
2894   NOT_YET_IMPLEMENTED
2895 }
2896
2897 int PMPI_Graph_neighbors_count(MPI_Comm comm, int rank, int* nneighbors) {
2898   NOT_YET_IMPLEMENTED
2899 }
2900
2901 int PMPI_Graphdims_get(MPI_Comm comm, int* nnodes, int* nedges) {
2902   NOT_YET_IMPLEMENTED
2903 }
2904
2905 int PMPI_Topo_test(MPI_Comm comm, int* top_type) {
2906   NOT_YET_IMPLEMENTED
2907 }
2908
2909 int PMPI_Errhandler_create(MPI_Handler_function* function, MPI_Errhandler* errhandler) {
2910   NOT_YET_IMPLEMENTED
2911 }
2912
2913 int PMPI_Errhandler_free(MPI_Errhandler* errhandler) {
2914   NOT_YET_IMPLEMENTED
2915 }
2916
2917 int PMPI_Errhandler_get(MPI_Comm comm, MPI_Errhandler* errhandler) {
2918   NOT_YET_IMPLEMENTED
2919 }
2920
2921 int PMPI_Error_string(int errorcode, char* string, int* resultlen) {
2922   NOT_YET_IMPLEMENTED
2923 }
2924
2925 int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler) {
2926   NOT_YET_IMPLEMENTED
2927 }
2928
2929 int PMPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler) {
2930   NOT_YET_IMPLEMENTED
2931 }
2932
2933 int PMPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler) {
2934   NOT_YET_IMPLEMENTED
2935 }
2936
2937 int PMPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler* errhandler) {
2938   NOT_YET_IMPLEMENTED
2939 }
2940
2941 int PMPI_Cancel(MPI_Request* request) {
2942   NOT_YET_IMPLEMENTED
2943 }
2944
2945 int PMPI_Buffer_attach(void* buffer, int size) {
2946   NOT_YET_IMPLEMENTED
2947 }
2948
2949 int PMPI_Buffer_detach(void* buffer, int* size) {
2950   NOT_YET_IMPLEMENTED
2951 }
2952
2953 int PMPI_Comm_test_inter(MPI_Comm comm, int* flag) {
2954   NOT_YET_IMPLEMENTED
2955 }
2956
2957 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
2958 {
2959   NOT_YET_IMPLEMENTED
2960 }
2961
2962 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
2963 {
2964   NOT_YET_IMPLEMENTED
2965 }
2966
2967 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
2968 {
2969   NOT_YET_IMPLEMENTED
2970 }
2971
2972 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval, void* extra_state)
2973 {
2974   NOT_YET_IMPLEMENTED
2975 }
2976
2977 int PMPI_Comm_free_keyval(int* keyval) {
2978   NOT_YET_IMPLEMENTED
2979 }
2980
2981 int PMPI_Pcontrol(const int level )
2982 {
2983   NOT_YET_IMPLEMENTED
2984 }
2985
2986 int PMPI_Unpack(void* inbuf, int insize, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
2987   NOT_YET_IMPLEMENTED
2988 }
2989
2990 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
2991 {
2992   NOT_YET_IMPLEMENTED
2993 }
2994
2995 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
2996 {
2997   NOT_YET_IMPLEMENTED
2998 }
2999
3000 int PMPI_Type_delete_attr (MPI_Datatype type, int comm_keyval)
3001 {
3002   NOT_YET_IMPLEMENTED
3003 }
3004
3005 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state)
3006 {
3007   NOT_YET_IMPLEMENTED
3008 }
3009
3010 int PMPI_Type_free_keyval(int* keyval) {
3011   NOT_YET_IMPLEMENTED
3012 }
3013
3014 int PMPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out) {
3015   NOT_YET_IMPLEMENTED
3016 }
3017
3018 int PMPI_Intercomm_merge(MPI_Comm comm, int high, MPI_Comm* comm_out) {
3019   NOT_YET_IMPLEMENTED
3020 }
3021
3022 int PMPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
3023   NOT_YET_IMPLEMENTED
3024 }
3025
3026 int PMPI_Bsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3027   NOT_YET_IMPLEMENTED
3028 }
3029
3030 int PMPI_Ibsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3031   NOT_YET_IMPLEMENTED
3032 }
3033
3034 int PMPI_Comm_remote_group(MPI_Comm comm, MPI_Group* group) {
3035   NOT_YET_IMPLEMENTED
3036 }
3037
3038 int PMPI_Comm_remote_size(MPI_Comm comm, int* size) {
3039   NOT_YET_IMPLEMENTED
3040 }
3041
3042 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3043   NOT_YET_IMPLEMENTED
3044 }
3045
3046 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3047   NOT_YET_IMPLEMENTED
3048 }
3049
3050 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3051   NOT_YET_IMPLEMENTED
3052 }
3053
3054 int PMPI_Rsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
3055   NOT_YET_IMPLEMENTED
3056 }
3057
3058 int PMPI_Rsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3059   NOT_YET_IMPLEMENTED
3060 }
3061
3062 int PMPI_Irsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3063   NOT_YET_IMPLEMENTED
3064 }
3065
3066 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3067   NOT_YET_IMPLEMENTED
3068 }
3069
3070 int PMPI_Keyval_free(int* keyval) {
3071   NOT_YET_IMPLEMENTED
3072 }
3073
3074 int PMPI_Test_cancelled(MPI_Status* status, int* flag) {
3075   NOT_YET_IMPLEMENTED
3076 }
3077
3078 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3079   NOT_YET_IMPLEMENTED
3080 }
3081
3082 int PMPI_Pack_external_size(char *datarep, int incount, MPI_Datatype datatype, MPI_Aint *size){
3083   NOT_YET_IMPLEMENTED
3084 }
3085
3086 int PMPI_Pack_external(char *datarep, void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, MPI_Aint outcount, MPI_Aint *position){
3087   NOT_YET_IMPLEMENTED
3088 }
3089
3090 int PMPI_Unpack_external( char *datarep, void *inbuf, MPI_Aint insize, MPI_Aint *position, void *outbuf, int outcount, MPI_Datatype datatype){
3091   NOT_YET_IMPLEMENTED
3092 }
3093
3094 int PMPI_Get_elements(MPI_Status* status, MPI_Datatype datatype, int* elements) {
3095   NOT_YET_IMPLEMENTED
3096 }
3097
3098 int PMPI_Info_create( MPI_Info *info){
3099   NOT_YET_IMPLEMENTED
3100 }
3101
3102 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3103   NOT_YET_IMPLEMENTED
3104 }
3105
3106 int PMPI_Info_free( MPI_Info *info){
3107   NOT_YET_IMPLEMENTED
3108 }
3109
3110 int PMPI_Type_get_envelope( MPI_Datatype datatype, int *num_integers,
3111                             int *num_addresses, int *num_datatypes, int *combiner){
3112   NOT_YET_IMPLEMENTED
3113 }
3114
3115 int PMPI_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses,
3116                            int max_datatypes, int* array_of_integers, MPI_Aint* array_of_addresses,
3117                            MPI_Datatype* array_of_datatypes){
3118   NOT_YET_IMPLEMENTED
3119 }
3120
3121 int PMPI_Type_create_darray(int size, int rank, int ndims, int* array_of_gsizes,
3122                             int* array_of_distribs, int* array_of_dargs, int* array_of_psizes,
3123                             int order, MPI_Datatype oldtype, MPI_Datatype *newtype) {
3124   NOT_YET_IMPLEMENTED
3125 }
3126
3127 int PMPI_Type_create_subarray(int ndims,int *array_of_sizes, int *array_of_subsizes, int *array_of_starts, int order, MPI_Datatype oldtype, MPI_Datatype *newtype){
3128   NOT_YET_IMPLEMENTED
3129 }
3130
3131 int PMPI_Type_match_size(int typeclass,int size,MPI_Datatype *datatype){
3132   NOT_YET_IMPLEMENTED
3133 }
3134
3135 int PMPI_Alltoallw( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes,
3136                     void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes,
3137                     MPI_Comm comm){
3138   NOT_YET_IMPLEMENTED
3139 }
3140
3141 int PMPI_Comm_set_name(MPI_Comm comm, char* name){
3142   NOT_YET_IMPLEMENTED
3143 }
3144
3145 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm){
3146   NOT_YET_IMPLEMENTED
3147 }
3148
3149 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm){
3150   NOT_YET_IMPLEMENTED
3151 }
3152
3153 int PMPI_Comm_set_info (MPI_Comm comm, MPI_Info info){
3154   NOT_YET_IMPLEMENTED
3155 }
3156
3157 int PMPI_Comm_get_info (MPI_Comm comm, MPI_Info* info){
3158   NOT_YET_IMPLEMENTED
3159 }
3160
3161 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3162   NOT_YET_IMPLEMENTED
3163 }
3164
3165 int PMPI_Comm_create_errhandler( MPI_Comm_errhandler_fn *function, MPI_Errhandler *errhandler){
3166   NOT_YET_IMPLEMENTED
3167 }
3168
3169 int PMPI_Add_error_class( int *errorclass){
3170   NOT_YET_IMPLEMENTED
3171 }
3172
3173 int PMPI_Add_error_code(  int errorclass, int *errorcode){
3174   NOT_YET_IMPLEMENTED
3175 }
3176
3177 int PMPI_Add_error_string( int errorcode, char *string){
3178   NOT_YET_IMPLEMENTED
3179 }
3180
3181 int PMPI_Comm_call_errhandler(MPI_Comm comm,int errorcode){
3182   NOT_YET_IMPLEMENTED
3183 }
3184
3185 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3186   NOT_YET_IMPLEMENTED
3187 }
3188
3189 int PMPI_Info_delete(MPI_Info info, char *key){
3190   NOT_YET_IMPLEMENTED
3191 }
3192
3193 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3194   NOT_YET_IMPLEMENTED
3195 }
3196
3197 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3198   NOT_YET_IMPLEMENTED
3199 }
3200
3201 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3202   NOT_YET_IMPLEMENTED
3203 }
3204
3205 int PMPI_Request_get_status( MPI_Request request, int *flag, MPI_Status *status){
3206   NOT_YET_IMPLEMENTED
3207 }
3208
3209 int PMPI_Grequest_start( MPI_Grequest_query_function *query_fn, MPI_Grequest_free_function *free_fn, MPI_Grequest_cancel_function *cancel_fn, void *extra_state, MPI_Request *request){
3210   NOT_YET_IMPLEMENTED
3211 }
3212
3213 int PMPI_Grequest_complete( MPI_Request request){
3214   NOT_YET_IMPLEMENTED
3215 }
3216
3217 int PMPI_Status_set_cancelled(MPI_Status *status,int flag){
3218   NOT_YET_IMPLEMENTED
3219 }
3220
3221 int PMPI_Status_set_elements( MPI_Status *status, MPI_Datatype datatype, int count){
3222   NOT_YET_IMPLEMENTED
3223 }
3224
3225 int PMPI_Comm_connect( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3226   NOT_YET_IMPLEMENTED
3227 }
3228
3229 int PMPI_Publish_name( char *service_name, MPI_Info info, char *port_name){
3230   NOT_YET_IMPLEMENTED
3231 }
3232
3233 int PMPI_Unpublish_name( char *service_name, MPI_Info info, char *port_name){
3234   NOT_YET_IMPLEMENTED
3235 }
3236
3237 int PMPI_Lookup_name( char *service_name, MPI_Info info, char *port_name){
3238   NOT_YET_IMPLEMENTED
3239 }
3240
3241 int PMPI_Comm_join( int fd, MPI_Comm *intercomm){
3242   NOT_YET_IMPLEMENTED
3243 }
3244
3245 int PMPI_Open_port( MPI_Info info, char *port_name){
3246   NOT_YET_IMPLEMENTED
3247 }
3248
3249 int PMPI_Close_port(char *port_name){
3250   NOT_YET_IMPLEMENTED
3251 }
3252
3253 int PMPI_Comm_accept( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3254   NOT_YET_IMPLEMENTED
3255 }
3256
3257 int PMPI_Comm_spawn( char *command, char **argv, int maxprocs, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *intercomm, int* array_of_errcodes){
3258   NOT_YET_IMPLEMENTED
3259 }
3260
3261 int PMPI_Comm_spawn_multiple( int count, char **array_of_commands, char*** array_of_argv,
3262                               int* array_of_maxprocs, MPI_Info* array_of_info, int root,
3263                               MPI_Comm comm, MPI_Comm *intercomm, int* array_of_errcodes){
3264   NOT_YET_IMPLEMENTED
3265 }
3266
3267 int PMPI_Comm_get_parent( MPI_Comm *parent){
3268   NOT_YET_IMPLEMENTED
3269 }