Logo AND Algorithmique Numérique Distribuée

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