Logo AND Algorithmique Numérique Distribuée

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