Logo AND Algorithmique Numérique Distribuée

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