Logo AND Algorithmique Numérique Distribuée

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