Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
make tracing work better with gatherv and scatterv
[simgrid.git] / src / smpi / smpi_pmpi.c
1
2 /* Copyright (c) 2007-2015. The SimGrid Team.
3  * All rights reserved.                                                     */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include "private.h"
9 #include "smpi_mpi_dt_private.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_pmpi, smpi,
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     if (!TRACE_smpi_view_internals()) {
1175       TRACE_smpi_recv(rank, src_traced, rank);
1176     }
1177   }
1178   TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
1179   }
1180
1181   smpi_bench_begin();
1182   return retval;
1183 }
1184
1185 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag,
1186              MPI_Comm comm)
1187 {
1188   int retval = 0;
1189
1190   smpi_bench_end();
1191
1192   if (comm == MPI_COMM_NULL) {
1193     retval = MPI_ERR_COMM;
1194   } else if (dst == MPI_PROC_NULL) {
1195     retval = MPI_SUCCESS;
1196   } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1197     retval = MPI_ERR_RANK;
1198   } else if (count < 0) {
1199     retval = MPI_ERR_COUNT;
1200   } else if (buf==NULL && count > 0) {
1201     retval = MPI_ERR_COUNT;
1202   } else if (!is_datatype_valid(datatype)) {
1203       retval = MPI_ERR_TYPE;
1204   } else if(tag<0 && tag !=  MPI_ANY_TAG){
1205     retval = MPI_ERR_TAG;
1206   } else {
1207
1208   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1209   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1210   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1211   extra->type = TRACING_SEND;
1212   extra->src = rank;
1213   extra->dst = dst_traced;
1214   int known=0;
1215   extra->datatype1 = encode_datatype(datatype, &known);
1216   int dt_size_send = 1;
1217   if(!known)
1218     dt_size_send = smpi_datatype_size(datatype);
1219   extra->send_size = count*dt_size_send;
1220   TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);
1221   if (!TRACE_smpi_view_internals()) {
1222     TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1223   }
1224
1225     smpi_mpi_send(buf, count, datatype, dst, tag, comm);
1226     retval = MPI_SUCCESS;
1227
1228   TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1229   }
1230
1231   smpi_bench_begin();
1232   return retval;
1233 }
1234
1235
1236
1237 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
1238   int retval = 0;
1239
1240    smpi_bench_end();
1241
1242    if (comm == MPI_COMM_NULL) {
1243      retval = MPI_ERR_COMM;
1244    } else if (dst == MPI_PROC_NULL) {
1245      retval = MPI_SUCCESS;
1246    } else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0){
1247      retval = MPI_ERR_RANK;
1248    } else if (count < 0) {
1249      retval = MPI_ERR_COUNT;
1250    } else if (buf==NULL && count > 0) {
1251      retval = MPI_ERR_COUNT;
1252    } else if (!is_datatype_valid(datatype)){
1253      retval = MPI_ERR_TYPE;
1254    } else if(tag<0 && tag !=  MPI_ANY_TAG){
1255      retval = MPI_ERR_TAG;
1256    } else {
1257
1258    int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1259    int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1260    instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1261    extra->type = TRACING_SSEND;
1262    extra->src = rank;
1263    extra->dst = dst_traced;
1264    int known=0;
1265    extra->datatype1 = encode_datatype(datatype, &known);
1266    int dt_size_send = 1;
1267    if(!known)
1268      dt_size_send = smpi_datatype_size(datatype);
1269    extra->send_size = count*dt_size_send;
1270    TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra);   TRACE_smpi_send(rank, rank, dst_traced,count*smpi_datatype_size(datatype));
1271
1272      smpi_mpi_ssend(buf, count, datatype, dst, tag, comm);
1273      retval = MPI_SUCCESS;
1274
1275    TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
1276    }
1277
1278    smpi_bench_begin();
1279    return retval;}
1280
1281
1282 int PMPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1283                  int dst, int sendtag, void *recvbuf, int recvcount,
1284                  MPI_Datatype recvtype, int src, int recvtag,
1285                  MPI_Comm comm, MPI_Status * status)
1286 {
1287   int retval = 0;
1288
1289   smpi_bench_end();
1290
1291   if (comm == MPI_COMM_NULL) {
1292     retval = MPI_ERR_COMM;
1293   } else if (!is_datatype_valid(sendtype)
1294              || !is_datatype_valid(recvtype)) {
1295     retval = MPI_ERR_TYPE;
1296   } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
1297       smpi_empty_status(status);
1298       status->MPI_SOURCE = MPI_PROC_NULL;
1299       retval = MPI_SUCCESS;
1300   }else if (dst >= smpi_group_size(smpi_comm_group(comm)) || dst <0 ||
1301       (src!=MPI_ANY_SOURCE && (src >= smpi_group_size(smpi_comm_group(comm)) || src <0))){
1302     retval = MPI_ERR_RANK;
1303   } else if (sendcount < 0 || recvcount<0) {
1304       retval = MPI_ERR_COUNT;
1305   } else if ((sendbuf==NULL && sendcount > 0)||(recvbuf==NULL && recvcount>0)) {
1306     retval = MPI_ERR_COUNT;
1307   } else if((sendtag<0 && sendtag !=  MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
1308     retval = MPI_ERR_TAG;
1309   } else {
1310
1311   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1312   int dst_traced = smpi_group_index(smpi_comm_group(comm), dst);
1313   int src_traced = smpi_group_index(smpi_comm_group(comm), src);
1314   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1315   extra->type = TRACING_SENDRECV;
1316   extra->src = src_traced;
1317   extra->dst = dst_traced;
1318   int known=0;
1319   extra->datatype1 = encode_datatype(sendtype, &known);
1320   int dt_size_send = 1;
1321   if(!known)
1322     dt_size_send = smpi_datatype_size(sendtype);
1323   extra->send_size = sendcount*dt_size_send;
1324   extra->datatype2 = encode_datatype(recvtype, &known);
1325   int dt_size_recv = 1;
1326   if(!known)
1327     dt_size_recv = smpi_datatype_size(recvtype);
1328   extra->recv_size = recvcount*dt_size_recv;
1329
1330   TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1331   TRACE_smpi_send(rank, rank, dst_traced,sendcount*smpi_datatype_size(sendtype));
1332
1333     smpi_mpi_sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf,
1334                       recvcount, recvtype, src, recvtag, comm, status);
1335     retval = MPI_SUCCESS;
1336
1337   TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1338   TRACE_smpi_recv(rank, src_traced, rank);
1339   }
1340
1341   smpi_bench_begin();
1342   return retval;
1343 }
1344
1345 int PMPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype,
1346                          int dst, int sendtag, int src, int recvtag,
1347                          MPI_Comm comm, MPI_Status * status)
1348 {
1349   //TODO: suboptimal implementation
1350   void *recvbuf;
1351   int retval = 0;
1352   if (!is_datatype_valid(datatype)) {
1353       retval = MPI_ERR_TYPE;
1354   } else if (count < 0) {
1355       retval = MPI_ERR_COUNT;
1356   } else {
1357     int size = smpi_datatype_get_extent(datatype) * count;
1358     recvbuf = xbt_new0(char, size);
1359     retval =
1360         MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count,
1361                      datatype, src, recvtag, comm, status);
1362     if(retval==MPI_SUCCESS){
1363         smpi_datatype_copy(recvbuf, count, datatype, buf, count, datatype);
1364     }
1365     xbt_free(recvbuf);
1366
1367   }
1368   return retval;
1369 }
1370
1371 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
1372 {
1373   int retval = 0;
1374   smpi_bench_end();
1375   if (request == NULL || flag == NULL) {
1376     retval = MPI_ERR_ARG;
1377   } else if (*request == MPI_REQUEST_NULL) {
1378     *flag= TRUE;
1379     smpi_empty_status(status);
1380     retval = MPI_SUCCESS;
1381   } else {
1382     int rank = request && (*request)->comm != MPI_COMM_NULL
1383       ? smpi_process_index()
1384       : -1;
1385
1386     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1387     extra->type = TRACING_TEST;
1388     TRACE_smpi_testing_in(rank, extra);
1389
1390     *flag = smpi_mpi_test(request, status);
1391
1392     TRACE_smpi_testing_out(rank);
1393     retval = MPI_SUCCESS;
1394   }
1395   smpi_bench_begin();
1396   return retval;
1397 }
1398
1399 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag,
1400                 MPI_Status * status)
1401 {
1402   int retval = 0;
1403
1404   smpi_bench_end();
1405   if (index == NULL || flag == NULL) {
1406     retval = MPI_ERR_ARG;
1407   } else {
1408     *flag = smpi_mpi_testany(count, requests, index, status);
1409     retval = MPI_SUCCESS;
1410   }
1411   smpi_bench_begin();
1412   return retval;
1413 }
1414
1415 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
1416 {
1417   int retval = 0;
1418
1419   smpi_bench_end();
1420   if (flag == NULL) {
1421     retval = MPI_ERR_ARG;
1422   } else {
1423     *flag = smpi_mpi_testall(count, requests, statuses);
1424     retval = MPI_SUCCESS;
1425   }
1426   smpi_bench_begin();
1427   return retval;
1428 }
1429
1430 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
1431   int retval = 0;
1432   smpi_bench_end();
1433
1434   if (status == NULL) {
1435     retval = MPI_ERR_ARG;
1436   } else if (comm == MPI_COMM_NULL) {
1437     retval = MPI_ERR_COMM;
1438   } else if (source == MPI_PROC_NULL) {
1439     smpi_empty_status(status);
1440     status->MPI_SOURCE = MPI_PROC_NULL;
1441     retval = MPI_SUCCESS;
1442   } else {
1443     smpi_mpi_probe(source, tag, comm, status);
1444     retval = MPI_SUCCESS;
1445   }
1446   smpi_bench_begin();
1447   return retval;
1448 }
1449
1450
1451 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
1452   int retval = 0;
1453   smpi_bench_end();
1454
1455   if (flag == NULL) {
1456     retval = MPI_ERR_ARG;
1457   } else if (status == NULL) {
1458     retval = MPI_ERR_ARG;
1459   } else if (comm == MPI_COMM_NULL) {
1460     retval = MPI_ERR_COMM;
1461   } else if (source == MPI_PROC_NULL) {
1462     *flag=TRUE;
1463     smpi_empty_status(status);
1464     status->MPI_SOURCE = MPI_PROC_NULL;
1465     retval = MPI_SUCCESS;
1466   } else {
1467     smpi_mpi_iprobe(source, tag, comm, flag, status);
1468     retval = MPI_SUCCESS;
1469   }
1470   smpi_bench_begin();
1471   return retval;
1472 }
1473
1474 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
1475 {
1476   int retval = 0;
1477
1478   smpi_bench_end();
1479
1480   smpi_empty_status(status);
1481
1482   if (request == NULL) {
1483     retval = MPI_ERR_ARG;
1484   } else if (*request == MPI_REQUEST_NULL) {
1485     retval = MPI_SUCCESS;
1486   } else {
1487
1488     int rank = request && (*request)->comm != MPI_COMM_NULL
1489       ? smpi_process_index()
1490       : -1;
1491
1492     int src_traced = (*request)->src;
1493     int dst_traced = (*request)->dst;
1494     MPI_Comm comm = (*request)->comm;
1495     int is_wait_for_receive = (*request)->recv;
1496     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1497     extra->type = TRACING_WAIT;
1498     TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra);
1499
1500     smpi_mpi_wait(request, status);
1501     retval = MPI_SUCCESS;
1502
1503     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1504     TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
1505     if (is_wait_for_receive) {
1506       if(src_traced==MPI_ANY_SOURCE)
1507         src_traced = (status!=MPI_STATUS_IGNORE) ?
1508           smpi_group_rank(smpi_comm_group(comm), status->MPI_SOURCE) :
1509           src_traced;
1510       TRACE_smpi_recv(rank, src_traced, dst_traced);
1511     }
1512   }
1513
1514   smpi_bench_begin();
1515   return retval;
1516 }
1517
1518 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
1519 {
1520   if (index == NULL)
1521     return MPI_ERR_ARG;
1522
1523   smpi_bench_end();
1524   //save requests information for tracing
1525   int i;
1526   int *srcs = xbt_new0(int, count);
1527   int *dsts = xbt_new0(int, count);
1528   int *recvs = xbt_new0(int, count);
1529   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1530
1531   for (i = 0; i < count; i++) {
1532     MPI_Request req = requests[i];      //already received requests are no longer valid
1533     if (req) {
1534       srcs[i] = req->src;
1535       dsts[i] = req->dst;
1536       recvs[i] = req->recv;
1537       comms[i] = req->comm;
1538     }
1539   }
1540   int rank_traced = smpi_process_index();
1541   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1542   extra->type = TRACING_WAITANY;
1543   extra->send_size=count;
1544   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1545
1546   *index = smpi_mpi_waitany(count, requests, status);
1547
1548   if(*index!=MPI_UNDEFINED){
1549     int src_traced = srcs[*index];
1550     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1551     int dst_traced = dsts[*index];
1552     int is_wait_for_receive = recvs[*index];
1553     if (is_wait_for_receive) {
1554       if(srcs[*index]==MPI_ANY_SOURCE)
1555         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1556                       smpi_group_rank(smpi_comm_group(comms[*index]), status->MPI_SOURCE) :
1557                       srcs[*index];
1558       TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1559     }
1560     TRACE_smpi_ptp_out(rank_traced, src_traced, dst_traced, __FUNCTION__);
1561     xbt_free(srcs);
1562     xbt_free(dsts);
1563     xbt_free(recvs);
1564     xbt_free(comms);
1565
1566   }
1567   smpi_bench_begin();
1568   return MPI_SUCCESS;
1569 }
1570
1571 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
1572 {
1573
1574   smpi_bench_end();
1575   //save information from requests
1576   int i;
1577   int *srcs = xbt_new0(int, count);
1578   int *dsts = xbt_new0(int, count);
1579   int *recvs = xbt_new0(int, count);
1580   int *valid = xbt_new0(int, count);
1581   MPI_Comm *comms = xbt_new0(MPI_Comm, count);
1582
1583   //int valid_count = 0;
1584   for (i = 0; i < count; i++) {
1585     MPI_Request req = requests[i];
1586     if(req!=MPI_REQUEST_NULL){
1587       srcs[i] = req->src;
1588       dsts[i] = req->dst;
1589       recvs[i] = req->recv;
1590       comms[i] = req->comm;
1591       valid[i]=1;;
1592     }else{
1593       valid[i]=0;
1594     }
1595   }
1596   int rank_traced = smpi_process_index();
1597   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1598   extra->type = TRACING_WAITALL;
1599   extra->send_size=count;
1600   TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__,extra);
1601
1602   int retval = smpi_mpi_waitall(count, requests, status);
1603
1604   for (i = 0; i < count; i++) {
1605     if(valid[i]){
1606     //int src_traced = srcs[*index];
1607     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
1608       int src_traced = srcs[i];
1609       int dst_traced = dsts[i];
1610       int is_wait_for_receive = recvs[i];
1611       if (is_wait_for_receive) {
1612         if(src_traced==MPI_ANY_SOURCE)
1613         src_traced = (status!=MPI_STATUSES_IGNORE) ?
1614                           smpi_group_rank(smpi_comm_group(comms[i]), status[i].MPI_SOURCE) :
1615                           srcs[i];
1616         TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
1617       }
1618     }
1619   }
1620   TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
1621   xbt_free(srcs);
1622   xbt_free(dsts);
1623   xbt_free(recvs);
1624   xbt_free(valid);
1625   xbt_free(comms);
1626
1627   smpi_bench_begin();
1628   return retval;
1629 }
1630
1631 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount,
1632                  int *indices, MPI_Status status[])
1633 {
1634   int retval = 0;
1635
1636   smpi_bench_end();
1637   if (outcount == NULL) {
1638     retval = MPI_ERR_ARG;
1639   } else {
1640     *outcount = smpi_mpi_waitsome(incount, requests, indices, status);
1641     retval = MPI_SUCCESS;
1642   }
1643   smpi_bench_begin();
1644   return retval;
1645 }
1646
1647 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount,
1648                  int* indices, MPI_Status status[])
1649 {
1650   int retval = 0;
1651
1652    smpi_bench_end();
1653    if (outcount == NULL) {
1654      retval = MPI_ERR_ARG;
1655    } else {
1656      *outcount = smpi_mpi_testsome(incount, requests, indices, status);
1657      retval = MPI_SUCCESS;
1658    }
1659    smpi_bench_begin();
1660    return retval;
1661 }
1662
1663
1664 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
1665 {
1666   int retval = 0;
1667
1668   smpi_bench_end();
1669
1670   if (comm == MPI_COMM_NULL) {
1671     retval = MPI_ERR_COMM;
1672   } else if (!is_datatype_valid(datatype)) {
1673       retval = MPI_ERR_ARG;
1674   } else {
1675   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1676   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1677
1678   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1679   extra->type = TRACING_BCAST;
1680   extra->root = root_traced;
1681   int known=0;
1682   extra->datatype1 = encode_datatype(datatype, &known);
1683   int dt_size_send = 1;
1684   if(!known)
1685     dt_size_send = smpi_datatype_size(datatype);
1686   extra->send_size = count*dt_size_send;
1687   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1688
1689     mpi_coll_bcast_fun(buf, count, datatype, root, comm);
1690     retval = MPI_SUCCESS;
1691
1692     TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1693   }
1694
1695   smpi_bench_begin();
1696   return retval;
1697 }
1698
1699 int PMPI_Barrier(MPI_Comm comm)
1700 {
1701   int retval = 0;
1702
1703   smpi_bench_end();
1704
1705   if (comm == MPI_COMM_NULL) {
1706     retval = MPI_ERR_COMM;
1707   } else {
1708   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1709   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1710   extra->type = TRACING_BARRIER;
1711   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1712
1713   mpi_coll_barrier_fun(comm);
1714   retval = MPI_SUCCESS;
1715
1716   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1717   }
1718
1719   smpi_bench_begin();
1720   return retval;
1721 }
1722
1723 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1724                void *recvbuf, int recvcount, MPI_Datatype recvtype,
1725                int root, MPI_Comm comm)
1726 {
1727   int retval = 0;
1728
1729   smpi_bench_end();
1730
1731   if (comm == MPI_COMM_NULL) {
1732     retval = MPI_ERR_COMM;
1733   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1734             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1735     retval = MPI_ERR_TYPE;
1736   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1737             ((smpi_comm_rank(comm) == root) && (recvcount <0))){
1738     retval = MPI_ERR_COUNT;
1739   } else {
1740
1741     char* sendtmpbuf = (char*) sendbuf;
1742     int sendtmpcount = sendcount;
1743     MPI_Datatype sendtmptype = sendtype;
1744     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1745       sendtmpcount=0;
1746       sendtmptype=recvtype;
1747     }
1748   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1749   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1750   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1751   extra->type = TRACING_GATHER;
1752   extra->root = root_traced;
1753   int known=0;
1754   extra->datatype1 = encode_datatype(sendtmptype, &known);
1755   int dt_size_send = 1;
1756   if(!known)
1757     dt_size_send = smpi_datatype_size(sendtmptype);
1758   extra->send_size = sendtmpcount*dt_size_send;
1759   extra->datatype2 = encode_datatype(recvtype, &known);
1760   int dt_size_recv = 1;
1761   if((smpi_comm_rank(comm)==root) && !known)
1762     dt_size_recv = smpi_datatype_size(recvtype);
1763   extra->recv_size = recvcount*dt_size_recv;
1764
1765   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__, extra);
1766
1767   mpi_coll_gather_fun(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount,
1768                     recvtype, root, comm);
1769
1770
1771     retval = MPI_SUCCESS;
1772   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1773   }
1774
1775   smpi_bench_begin();
1776   return retval;
1777 }
1778
1779 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1780                 void *recvbuf, int *recvcounts, int *displs,
1781                 MPI_Datatype recvtype, int root, MPI_Comm comm)
1782 {
1783   int retval = 0;
1784
1785   smpi_bench_end();
1786
1787   if (comm == MPI_COMM_NULL) {
1788     retval = MPI_ERR_COMM;
1789   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1790             ((smpi_comm_rank(comm) == root) && (recvtype == MPI_DATATYPE_NULL))){
1791     retval = MPI_ERR_TYPE;
1792   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1793     retval = MPI_ERR_COUNT;
1794   } else if (recvcounts == NULL || displs == NULL) {
1795     retval = MPI_ERR_ARG;
1796   } else {
1797     char* sendtmpbuf = (char*) sendbuf;
1798     int sendtmpcount = sendcount;
1799     MPI_Datatype sendtmptype = sendtype;
1800     if( (smpi_comm_rank(comm) == root) && (sendbuf == MPI_IN_PLACE )) {
1801       sendtmpcount=0;
1802       sendtmptype=recvtype;
1803     }
1804
1805   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1806   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1807   int i=0;
1808   int size = smpi_comm_size(comm);
1809   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1810   extra->type = TRACING_GATHERV;
1811   extra->num_processes = size;
1812   extra->root = root_traced;
1813   int known=0;
1814   extra->datatype1 = encode_datatype(sendtmptype, &known);
1815   int dt_size_send = 1;
1816   if(!known)
1817     dt_size_send = smpi_datatype_size(sendtype);
1818   extra->send_size = sendtmpcount*dt_size_send;
1819   extra->datatype2 = encode_datatype(recvtype, &known);
1820   int dt_size_recv = 1;
1821   if(!known)
1822     dt_size_recv = smpi_datatype_size(recvtype);
1823   if((smpi_comm_rank(comm)==root)){
1824   extra->recvcounts= xbt_malloc(size*sizeof(int));
1825   for(i=0; i< size; i++)//copy data to avoid bad free
1826     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
1827   }
1828   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1829
1830   smpi_mpi_gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts,
1831                      displs, recvtype, root, comm);
1832     retval = MPI_SUCCESS;
1833   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1834   }
1835
1836   smpi_bench_begin();
1837   return retval;
1838 }
1839
1840 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1841                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
1842                   MPI_Comm comm)
1843 {
1844   int retval = 0;
1845
1846   smpi_bench_end();
1847
1848   if (comm == MPI_COMM_NULL) {
1849     retval = MPI_ERR_COMM;
1850   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1851             (recvtype == MPI_DATATYPE_NULL)){
1852     retval = MPI_ERR_TYPE;
1853   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1854             (recvcount <0)){
1855     retval = MPI_ERR_COUNT;
1856   } else {
1857     if(sendbuf == MPI_IN_PLACE) {
1858       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*recvcount*smpi_comm_rank(comm);
1859       sendcount=recvcount;
1860       sendtype=recvtype;
1861     }
1862   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1863   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1864   extra->type = TRACING_ALLGATHER;
1865   int known=0;
1866   extra->datatype1 = encode_datatype(sendtype, &known);
1867   int dt_size_send = 1;
1868   if(!known)
1869     dt_size_send = smpi_datatype_size(sendtype);
1870   extra->send_size = sendcount*dt_size_send;
1871   extra->datatype2 = encode_datatype(recvtype, &known);
1872   int dt_size_recv = 1;
1873   if(!known)
1874     dt_size_recv = smpi_datatype_size(recvtype);
1875   extra->recv_size = recvcount*dt_size_recv;
1876
1877   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1878
1879   mpi_coll_allgather_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1880                            recvtype, comm);
1881     retval = MPI_SUCCESS;
1882   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1883   }
1884   smpi_bench_begin();
1885   return retval;
1886 }
1887
1888 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1889                    void *recvbuf, int *recvcounts, int *displs,
1890                    MPI_Datatype recvtype, MPI_Comm comm)
1891 {
1892   int retval = 0;
1893
1894   smpi_bench_end();
1895
1896   if (comm == MPI_COMM_NULL) {
1897     retval = MPI_ERR_COMM;
1898   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1899             (recvtype == MPI_DATATYPE_NULL)){
1900     retval = MPI_ERR_TYPE;
1901   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1902     retval = MPI_ERR_COUNT;
1903   } else if (recvcounts == NULL || displs == NULL) {
1904     retval = MPI_ERR_ARG;
1905   } else {
1906
1907     if(sendbuf == MPI_IN_PLACE) {
1908       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*displs[smpi_comm_rank(comm)];
1909       sendcount=recvcounts[smpi_comm_rank(comm)];
1910       sendtype=recvtype;
1911     }
1912   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1913   int i=0;
1914   int size = smpi_comm_size(comm);
1915   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1916   extra->type = TRACING_ALLGATHERV;
1917   extra->num_processes = size;
1918   int known=0;
1919   extra->datatype1 = encode_datatype(sendtype, &known);
1920   int dt_size_send = 1;
1921   if(!known)
1922     dt_size_send = smpi_datatype_size(sendtype);
1923   extra->send_size = sendcount*dt_size_send;
1924   extra->datatype2 = encode_datatype(recvtype, &known);
1925   int dt_size_recv = 1;
1926   if(!known)
1927     dt_size_recv = smpi_datatype_size(recvtype);
1928   extra->recvcounts= xbt_malloc(size*sizeof(int));
1929   for(i=0; i< size; i++)//copy data to avoid bad free
1930     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
1931
1932   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
1933
1934     mpi_coll_allgatherv_fun(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
1935                         displs, recvtype, comm);
1936     retval = MPI_SUCCESS;
1937   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1938   }
1939
1940   smpi_bench_begin();
1941   return retval;
1942 }
1943
1944 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1945                 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1946                 int root, MPI_Comm comm)
1947 {
1948   int retval = 0;
1949
1950   smpi_bench_end();
1951
1952   if (comm == MPI_COMM_NULL) {
1953     retval = MPI_ERR_COMM;
1954   } else if (((smpi_comm_rank(comm)==root) && (!is_datatype_valid(sendtype)))
1955              || ((recvbuf !=MPI_IN_PLACE) && (!is_datatype_valid(recvtype)))){
1956     retval = MPI_ERR_TYPE;
1957   } else if ((sendbuf == recvbuf) ||
1958       ((smpi_comm_rank(comm)==root) && sendcount>0 && (sendbuf == NULL))){
1959     retval = MPI_ERR_BUFFER;
1960   }else {
1961
1962     if (recvbuf == MPI_IN_PLACE) {
1963         recvtype=sendtype;
1964         recvcount=sendcount;
1965     }
1966   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1967   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1968   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1969   extra->type = TRACING_SCATTER;
1970   extra->root = root_traced;
1971   int known=0;
1972   extra->datatype1 = encode_datatype(sendtype, &known);
1973   int dt_size_send = 1;
1974   if((smpi_comm_rank(comm)==root) && !known)
1975     dt_size_send = smpi_datatype_size(sendtype);
1976   extra->send_size = sendcount*dt_size_send;
1977   extra->datatype2 = encode_datatype(recvtype, &known);
1978   int dt_size_recv = 1;
1979   if(!known)
1980     dt_size_recv = smpi_datatype_size(recvtype);
1981   extra->recv_size = recvcount*dt_size_recv;
1982   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1983
1984   mpi_coll_scatter_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1985                      recvtype, root, comm);
1986     retval = MPI_SUCCESS;
1987   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1988   }
1989
1990   smpi_bench_begin();
1991   return retval;
1992 }
1993
1994 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1995                  MPI_Datatype sendtype, void *recvbuf, int recvcount,
1996                  MPI_Datatype recvtype, int root, MPI_Comm comm)
1997 {
1998   int retval = 0;
1999
2000   smpi_bench_end();
2001
2002   if (comm == MPI_COMM_NULL) {
2003     retval = MPI_ERR_COMM;
2004   } else if (sendcounts == NULL || displs == NULL) {
2005     retval = MPI_ERR_ARG;
2006   } else if (((smpi_comm_rank(comm)==root) && (sendtype == MPI_DATATYPE_NULL))
2007              || ((recvbuf !=MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
2008     retval = MPI_ERR_TYPE;
2009   } else {
2010     if (recvbuf == MPI_IN_PLACE) {
2011         recvtype=sendtype;
2012         recvcount=sendcounts[smpi_comm_rank(comm)];
2013     }
2014   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2015   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2016   int i=0;
2017   int size = smpi_comm_size(comm);
2018   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2019   extra->type = TRACING_SCATTERV;
2020   extra->num_processes = size;
2021   extra->root = root_traced;
2022   int known=0;
2023   extra->datatype1 = encode_datatype(sendtype, &known);
2024   int dt_size_send = 1;
2025   if(!known)
2026     dt_size_send = smpi_datatype_size(sendtype);
2027   if((smpi_comm_rank(comm)==root)){
2028   extra->sendcounts= xbt_malloc(size*sizeof(int));
2029   for(i=0; i< size; i++)//copy data to avoid bad free
2030     extra->sendcounts[i] = sendcounts[i]*dt_size_send;
2031   }
2032   extra->datatype2 = encode_datatype(recvtype, &known);
2033   int dt_size_recv = 1;
2034   if(!known)
2035     dt_size_recv = smpi_datatype_size(recvtype);
2036   extra->recv_size = recvcount*dt_size_recv;
2037   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2038
2039     smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf,
2040                       recvcount, recvtype, root, comm);
2041
2042     retval = MPI_SUCCESS;
2043   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2044   }
2045
2046   smpi_bench_begin();
2047   return retval;
2048 }
2049
2050 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
2051                MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
2052 {
2053   int retval = 0;
2054
2055   smpi_bench_end();
2056
2057   if (comm == MPI_COMM_NULL) {
2058     retval = MPI_ERR_COMM;
2059   } else if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2060     retval = MPI_ERR_ARG;
2061   } else {
2062   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2063   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2064   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2065   extra->type = TRACING_REDUCE;
2066   int known=0;
2067   extra->datatype1 = encode_datatype(datatype, &known);
2068   int dt_size_send = 1;
2069   if(!known)
2070     dt_size_send = smpi_datatype_size(datatype);
2071   extra->send_size = count*dt_size_send;
2072   extra->root = root_traced;
2073
2074   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2075
2076   mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, root, comm);
2077
2078     retval = MPI_SUCCESS;
2079   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2080   }
2081
2082   smpi_bench_begin();
2083   return retval;
2084 }
2085
2086 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count,
2087     MPI_Datatype datatype, MPI_Op op){
2088   int retval = 0;
2089
2090     smpi_bench_end();
2091     if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2092       retval = MPI_ERR_ARG;
2093     } else {
2094       smpi_op_apply(op, inbuf, inoutbuf, &count, &datatype);
2095       retval=MPI_SUCCESS;
2096     }
2097     smpi_bench_begin();
2098     return retval;
2099 }
2100
2101 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
2102                   MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2103 {
2104   int retval = 0;
2105
2106   smpi_bench_end();
2107
2108   if (comm == MPI_COMM_NULL) {
2109     retval = MPI_ERR_COMM;
2110   } else if (!is_datatype_valid(datatype)) {
2111     retval = MPI_ERR_TYPE;
2112   } else if (op == MPI_OP_NULL) {
2113     retval = MPI_ERR_OP;
2114   } else {
2115
2116     char* sendtmpbuf = (char*) sendbuf;
2117     if( sendbuf == MPI_IN_PLACE ) {
2118       sendtmpbuf = (char *)xbt_malloc(count*smpi_datatype_get_extent(datatype));
2119       smpi_datatype_copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
2120     }
2121   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2122   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2123   extra->type = TRACING_ALLREDUCE;
2124   int known=0;
2125   extra->datatype1 = encode_datatype(datatype, &known);
2126   int dt_size_send = 1;
2127   if(!known)
2128     dt_size_send = smpi_datatype_size(datatype);
2129   extra->send_size = count*dt_size_send;
2130
2131   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2132
2133   mpi_coll_allreduce_fun(sendtmpbuf, recvbuf, count, datatype, op, comm);
2134
2135     if( sendbuf == MPI_IN_PLACE )
2136       xbt_free(sendtmpbuf);
2137
2138     retval = MPI_SUCCESS;
2139   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2140   }
2141
2142   smpi_bench_begin();
2143   return retval;
2144 }
2145
2146 int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
2147              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2148 {
2149   int retval = 0;
2150
2151   smpi_bench_end();
2152
2153   if (comm == MPI_COMM_NULL) {
2154     retval = MPI_ERR_COMM;
2155   } else if (!is_datatype_valid(datatype)) {
2156     retval = MPI_ERR_TYPE;
2157   } else if (op == MPI_OP_NULL) {
2158     retval = MPI_ERR_OP;
2159   } else {
2160   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2161   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2162   extra->type = TRACING_SCAN;
2163   int known=0;
2164   extra->datatype1 = encode_datatype(datatype, &known);
2165   int dt_size_send = 1;
2166   if(!known)
2167     dt_size_send = smpi_datatype_size(datatype);
2168   extra->send_size = count*dt_size_send;
2169
2170   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2171
2172   smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
2173
2174   retval = MPI_SUCCESS;
2175   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2176   }
2177
2178   smpi_bench_begin();
2179   return retval;
2180 }
2181
2182 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
2183                 MPI_Op op, MPI_Comm comm){
2184   int retval = 0;
2185
2186   smpi_bench_end();
2187
2188   if (comm == MPI_COMM_NULL) {
2189     retval = MPI_ERR_COMM;
2190   } else if (!is_datatype_valid(datatype)) {
2191     retval = MPI_ERR_TYPE;
2192   } else if (op == MPI_OP_NULL) {
2193     retval = MPI_ERR_OP;
2194   } else {
2195   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2196   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2197   extra->type = TRACING_EXSCAN;
2198   int known=0;
2199   extra->datatype1 = encode_datatype(datatype, &known);
2200   int dt_size_send = 1;
2201   if(!known)
2202     dt_size_send = smpi_datatype_size(datatype);
2203   extra->send_size = count*dt_size_send;
2204   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2205
2206   smpi_mpi_exscan(sendbuf, recvbuf, count, datatype, op, comm);
2207     retval = MPI_SUCCESS;
2208   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2209   }
2210
2211   smpi_bench_begin();
2212   return retval;
2213 }
2214
2215 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
2216                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2217 {
2218   int retval = 0;
2219   smpi_bench_end();
2220
2221   if (comm == MPI_COMM_NULL) {
2222     retval = MPI_ERR_COMM;
2223   } else if (!is_datatype_valid(datatype)) {
2224     retval = MPI_ERR_TYPE;
2225   } else if (op == MPI_OP_NULL) {
2226     retval = MPI_ERR_OP;
2227   } else if (recvcounts == NULL) {
2228     retval = MPI_ERR_ARG;
2229   } else {
2230   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2231   int i=0;
2232   int size = smpi_comm_size(comm);
2233   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2234   extra->type = TRACING_REDUCE_SCATTER;
2235   extra->num_processes = size;
2236   int known=0;
2237   extra->datatype1 = encode_datatype(datatype, &known);
2238   int dt_size_send = 1;
2239   if(!known)
2240     dt_size_send = smpi_datatype_size(datatype);
2241   extra->send_size = 0;
2242   extra->recvcounts= xbt_malloc(size*sizeof(int));
2243   for(i=0; i< size; i++)//copy data to avoid bad free
2244     extra->recvcounts[i] = recvcounts[i]*dt_size_send;
2245   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2246
2247   void* sendtmpbuf=sendbuf;
2248     if(sendbuf==MPI_IN_PLACE)
2249       sendtmpbuf=recvbuf;
2250
2251     mpi_coll_reduce_scatter_fun(sendtmpbuf, recvbuf, recvcounts,
2252                        datatype,  op, comm);
2253     retval = MPI_SUCCESS;
2254   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2255   }
2256
2257   smpi_bench_begin();
2258   return retval;
2259 }
2260
2261 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
2262                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2263 {
2264   int retval,i;
2265   smpi_bench_end();
2266
2267   if (comm == MPI_COMM_NULL) {
2268     retval = MPI_ERR_COMM;
2269   } else if (!is_datatype_valid(datatype)) {
2270     retval = MPI_ERR_TYPE;
2271   } else if (op == MPI_OP_NULL) {
2272     retval = MPI_ERR_OP;
2273   } else if (recvcount < 0) {
2274     retval = MPI_ERR_ARG;
2275   } else {
2276     int count=smpi_comm_size(comm);
2277
2278   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2279   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2280   extra->type = TRACING_REDUCE_SCATTER;
2281   extra->num_processes = count;
2282   int known=0;
2283   extra->datatype1 = encode_datatype(datatype, &known);
2284   int dt_size_send = 1;
2285   if(!known)
2286     dt_size_send = smpi_datatype_size(datatype);
2287   extra->send_size = 0;
2288   extra->recvcounts= xbt_malloc(count*sizeof(int));
2289   for(i=0; i< count; i++)//copy data to avoid bad free
2290     extra->recvcounts[i] = recvcount*dt_size_send;
2291
2292   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2293
2294   int* recvcounts=(int*)xbt_malloc(count);
2295     for (i=0; i<count;i++)recvcounts[i]=recvcount;
2296     mpi_coll_reduce_scatter_fun(sendbuf, recvbuf, recvcounts,
2297                        datatype,  op, comm);
2298     xbt_free(recvcounts);
2299     retval = MPI_SUCCESS;
2300
2301     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2302   }
2303
2304   smpi_bench_begin();
2305   return retval;
2306 }
2307
2308 int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
2309                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
2310                  MPI_Comm comm)
2311 {
2312   int retval = 0;
2313
2314   smpi_bench_end();
2315
2316   if (comm == MPI_COMM_NULL) {
2317     retval = MPI_ERR_COMM;
2318   } else if (sendtype == MPI_DATATYPE_NULL
2319              || recvtype == MPI_DATATYPE_NULL) {
2320     retval = MPI_ERR_TYPE;
2321   } else {
2322   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2323   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2324   extra->type = TRACING_ALLTOALL;
2325   int known=0;
2326   extra->datatype1 = encode_datatype(sendtype, &known);
2327   if(!known)
2328     extra->send_size = sendcount*smpi_datatype_size(sendtype);
2329   else
2330     extra->send_size = sendcount;
2331   extra->datatype2 = encode_datatype(recvtype, &known);
2332   if(!known)
2333     extra->recv_size = recvcount*smpi_datatype_size(recvtype);
2334   else
2335     extra->recv_size = recvcount;
2336   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2337
2338   retval = mpi_coll_alltoall_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
2339
2340   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2341   }
2342
2343   smpi_bench_begin();
2344   return retval;
2345 }
2346
2347 int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
2348                   MPI_Datatype sendtype, void *recvbuf, int *recvcounts,
2349                   int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2350 {
2351   int retval = 0;
2352
2353   smpi_bench_end();
2354
2355   if (comm == MPI_COMM_NULL) {
2356     retval = MPI_ERR_COMM;
2357   } else if (sendtype == MPI_DATATYPE_NULL
2358              || recvtype == MPI_DATATYPE_NULL) {
2359     retval = MPI_ERR_TYPE;
2360   } else if (sendcounts == NULL || senddisps == NULL || recvcounts == NULL
2361              || recvdisps == NULL) {
2362     retval = MPI_ERR_ARG;
2363   } else {
2364   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2365   int i=0;
2366   int size = smpi_comm_size(comm);
2367   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2368   extra->type = TRACING_ALLTOALLV;
2369   extra->send_size = 0;
2370   extra->recv_size = 0;
2371   extra->recvcounts= xbt_malloc(size*sizeof(int));
2372   extra->sendcounts= xbt_malloc(size*sizeof(int));
2373   int known=0;
2374   extra->datatype1 = encode_datatype(sendtype, &known);
2375   int dt_size_send = 1;
2376   if(!known)
2377     dt_size_send = smpi_datatype_size(sendtype);
2378   int dt_size_recv = 1;
2379   extra->datatype2 = encode_datatype(recvtype, &known);
2380   if(!known)
2381     dt_size_recv = smpi_datatype_size(recvtype);
2382   for(i=0; i< size; i++){//copy data to avoid bad free
2383     extra->send_size += sendcounts[i]*dt_size_send;
2384     extra->recv_size += recvcounts[i]*dt_size_recv;
2385
2386     extra->sendcounts[i] = sendcounts[i]*dt_size_send;
2387     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
2388   }
2389   extra->num_processes = size;
2390   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2391
2392   retval =
2393         mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps, sendtype,
2394                                   recvbuf, recvcounts, recvdisps, recvtype,
2395                                   comm);
2396   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2397   }
2398
2399   smpi_bench_begin();
2400   return retval;
2401 }
2402
2403
2404 int PMPI_Get_processor_name(char *name, int *resultlen)
2405 {
2406   int retval = MPI_SUCCESS;
2407
2408   strncpy(name, SIMIX_host_get_name(SIMIX_host_self()),
2409           strlen(SIMIX_host_get_name(SIMIX_host_self())) < MPI_MAX_PROCESSOR_NAME - 1 ?
2410           strlen(SIMIX_host_get_name(SIMIX_host_self())) +1 :
2411           MPI_MAX_PROCESSOR_NAME - 1 );
2412   *resultlen =
2413       strlen(name) >
2414       MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2415
2416   return retval;
2417 }
2418
2419 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2420 {
2421   int retval = MPI_SUCCESS;
2422   size_t size;
2423
2424   if (status == NULL || count == NULL) {
2425     retval = MPI_ERR_ARG;
2426   } else if (!is_datatype_valid(datatype)) {
2427     retval = MPI_ERR_TYPE;
2428   } else {
2429     size = smpi_datatype_size(datatype);
2430     if (size == 0) {
2431       *count = 0;
2432     } else if (status->count % size != 0) {
2433       retval = MPI_UNDEFINED;
2434     } else {
2435       *count = smpi_mpi_get_count(status, datatype);
2436     }
2437   }
2438   return retval;
2439 }
2440
2441 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2442   int retval = 0;
2443
2444   if (old_type == MPI_DATATYPE_NULL) {
2445     retval = MPI_ERR_TYPE;
2446   } else if (count<0){
2447     retval = MPI_ERR_COUNT;
2448   } else {
2449     retval = smpi_datatype_contiguous(count, old_type, new_type, 0);
2450   }
2451   return retval;
2452 }
2453
2454 int PMPI_Type_commit(MPI_Datatype* datatype) {
2455   int retval = 0;
2456
2457   if (datatype == NULL || *datatype == MPI_DATATYPE_NULL) {
2458     retval = MPI_ERR_TYPE;
2459   } else {
2460     smpi_datatype_commit(datatype);
2461     retval = MPI_SUCCESS;
2462   }
2463   return retval;
2464 }
2465
2466
2467 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2468   int retval = 0;
2469
2470   if (old_type == MPI_DATATYPE_NULL) {
2471     retval = MPI_ERR_TYPE;
2472   } else if (count<0 || blocklen<0){
2473     retval = MPI_ERR_COUNT;
2474   } else {
2475     retval = smpi_datatype_vector(count, blocklen, stride, old_type, new_type);
2476   }
2477   return retval;
2478 }
2479
2480 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2481   int retval = 0;
2482
2483   if (old_type == MPI_DATATYPE_NULL) {
2484     retval = MPI_ERR_TYPE;
2485   } else if (count<0 || blocklen<0){
2486     retval = MPI_ERR_COUNT;
2487   } else {
2488     retval = smpi_datatype_hvector(count, blocklen, stride, old_type, new_type);
2489   }
2490   return retval;
2491 }
2492
2493 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2494   return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2495 }
2496
2497 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2498   int retval = 0;
2499
2500   if (old_type == MPI_DATATYPE_NULL) {
2501     retval = MPI_ERR_TYPE;
2502   } else if (count<0){
2503     retval = MPI_ERR_COUNT;
2504   } else {
2505     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2506   }
2507   return retval;
2508 }
2509
2510 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2511   int retval = 0;
2512
2513   if (old_type == MPI_DATATYPE_NULL) {
2514     retval = MPI_ERR_TYPE;
2515   } else if (count<0){
2516     retval = MPI_ERR_COUNT;
2517   } else {
2518     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2519   }
2520   return retval;
2521 }
2522
2523 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2524   int retval,i;
2525
2526   if (old_type == MPI_DATATYPE_NULL) {
2527     retval = MPI_ERR_TYPE;
2528   } else if (count<0){
2529     retval = MPI_ERR_COUNT;
2530   } else {
2531     int* blocklens=(int*)xbt_malloc(blocklength*count);
2532     for (i=0; i<count;i++)blocklens[i]=blocklength;
2533     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2534     xbt_free(blocklens);
2535   }
2536   return retval;
2537 }
2538
2539
2540 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2541   int retval = 0;
2542
2543   if (old_type == MPI_DATATYPE_NULL) {
2544     retval = MPI_ERR_TYPE;
2545   } else if (count<0){
2546     retval = MPI_ERR_COUNT;
2547   } else {
2548     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2549   }
2550   return retval;
2551 }
2552
2553 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2554   return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2555 }
2556
2557 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2558   int retval,i;
2559
2560   if (old_type == MPI_DATATYPE_NULL) {
2561     retval = MPI_ERR_TYPE;
2562   } else if (count<0){
2563     retval = MPI_ERR_COUNT;
2564   } else {
2565     int* blocklens=(int*)xbt_malloc(blocklength*count);
2566     for (i=0; i<count;i++)blocklens[i]=blocklength;
2567     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2568     xbt_free(blocklens);
2569   }
2570   return retval;
2571 }
2572
2573
2574 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2575   int retval = 0;
2576
2577   if (count<0){
2578     retval = MPI_ERR_COUNT;
2579   } else {
2580     retval = smpi_datatype_struct(count, blocklens, indices, old_types, new_type);
2581   }
2582   return retval;
2583 }
2584
2585 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2586   return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2587 }
2588
2589
2590 int PMPI_Error_class(int errorcode, int* errorclass) {
2591   // assume smpi uses only standard mpi error codes
2592   *errorclass=errorcode;
2593   return MPI_SUCCESS;
2594 }
2595
2596
2597 int PMPI_Initialized(int* flag) {
2598    *flag=smpi_process_initialized();
2599    return MPI_SUCCESS;
2600 }
2601
2602 /* The topo part of MPI_COMM_WORLD should always be NULL. When other topologies
2603  * will be implemented, not only should we check if the topology is NULL, but
2604  * we should check if it is the good topology type (so we have to add a
2605  *  MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2606
2607 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2608   int retval = 0;
2609   if (comm_old == MPI_COMM_NULL){
2610     retval =  MPI_ERR_COMM;
2611   } else if (ndims < 0 ||
2612            (ndims > 0 && (dims == NULL ||
2613                           periodic == NULL)) ||
2614            comm_cart == NULL) {
2615     retval = MPI_ERR_ARG;
2616   } else{
2617     retval = smpi_mpi_cart_create(comm_old, ndims, dims, periodic, reorder, comm_cart);
2618   }
2619   return retval;
2620 }
2621
2622 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2623   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2624     return MPI_ERR_TOPOLOGY;
2625   }
2626   if (coords == NULL) {
2627     return MPI_ERR_ARG;
2628   }
2629   return smpi_mpi_cart_rank(comm, coords, rank);
2630 }
2631
2632 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2633   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2634     return MPI_ERR_TOPOLOGY;
2635   }
2636   if (source == NULL || dest == NULL || direction < 0 ) {
2637     return MPI_ERR_ARG;
2638   }
2639   return smpi_mpi_cart_shift(comm, direction, displ, source, dest);
2640 }
2641
2642 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2643   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2644     return MPI_ERR_TOPOLOGY;
2645   }
2646   if (rank < 0 || rank >= smpi_comm_size(comm)) {
2647     return MPI_ERR_RANK;
2648   }
2649   if (maxdims <= 0) {
2650     return MPI_ERR_ARG;
2651   }
2652   if(coords == NULL) {
2653     return MPI_ERR_ARG;
2654   }
2655   return smpi_mpi_cart_coords(comm, rank, maxdims, coords);
2656 }
2657
2658 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2659   if(comm == NULL || smpi_comm_topo(comm) == NULL) {
2660     return MPI_ERR_TOPOLOGY;
2661   }
2662   if(maxdims <= 0 || dims == NULL || periods == NULL || coords == NULL) {
2663     return MPI_ERR_ARG;
2664   }
2665   return smpi_mpi_cart_get(comm, maxdims, dims, periods, coords);
2666 }
2667
2668 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2669   if (comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2670     return MPI_ERR_TOPOLOGY;
2671   }
2672   if (ndims == NULL) {
2673     return MPI_ERR_ARG;
2674   }
2675   return smpi_mpi_cartdim_get(comm, ndims);
2676 }
2677
2678 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2679   if(dims == NULL) {
2680     return MPI_ERR_ARG;
2681   }
2682   if (ndims < 1 || nnodes < 1) {
2683     return MPI_ERR_DIMS;
2684   }
2685
2686   return smpi_mpi_dims_create(nnodes, ndims, dims);
2687 }
2688
2689 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2690   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2691     return MPI_ERR_TOPOLOGY;
2692   }
2693   if (comm_new == NULL) {
2694     return MPI_ERR_ARG;
2695   }
2696   return smpi_mpi_cart_sub(comm, remain_dims, comm_new);
2697 }
2698
2699 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2700     if(oldtype == MPI_DATATYPE_NULL) {
2701         return MPI_ERR_TYPE;
2702     }
2703     int blocks[3] = { 1, 1, 1 };
2704     MPI_Aint disps[3] = { lb, 0, lb+extent };
2705     MPI_Datatype types[3] = { MPI_LB, oldtype, MPI_UB };
2706
2707     s_smpi_mpi_struct_t* subtype = smpi_datatype_struct_create( blocks,
2708                                                                 disps,
2709                                                                 3,
2710                                                                 types
2711                                                                 );
2712     smpi_datatype_create(newtype,oldtype->size, lb, lb + extent, 1 , subtype, DT_FLAG_VECTOR);
2713
2714     (*newtype)->flags &= ~DT_FLAG_COMMITED;
2715     return MPI_SUCCESS;
2716 }
2717
2718
2719
2720 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2721   int retval = 0;
2722   smpi_bench_end();
2723   if (comm == MPI_COMM_NULL) {
2724     retval= MPI_ERR_COMM;
2725   }else if ((base == NULL && size != 0)
2726             || disp_unit <= 0 || size < 0 ){
2727     retval= MPI_ERR_OTHER;
2728   }else{
2729     *win = smpi_mpi_win_create( base, size, disp_unit, info, comm);
2730     retval = MPI_SUCCESS;
2731   }
2732   smpi_bench_begin();
2733   return retval;
2734 }
2735
2736 int PMPI_Win_free( MPI_Win* win){
2737   int retval = 0;
2738   smpi_bench_end();
2739   if (win == NULL || *win == MPI_WIN_NULL) {
2740     retval = MPI_ERR_WIN;
2741   }else{
2742     retval=smpi_mpi_win_free(win);
2743   }
2744   smpi_bench_begin();
2745   return retval;
2746 }
2747
2748 int PMPI_Win_set_name(MPI_Win  win, char * name)
2749 {
2750   int retval = 0;
2751   if (win == MPI_WIN_NULL)  {
2752     retval = MPI_ERR_TYPE;
2753   } else if (name == NULL)  {
2754     retval = MPI_ERR_ARG;
2755   } else {
2756     smpi_mpi_win_set_name(win, name);
2757     retval = MPI_SUCCESS;
2758   }
2759   return retval;
2760 }
2761
2762 int PMPI_Win_get_name(MPI_Win  win, char * name, int* len)
2763 {
2764   int retval = MPI_SUCCESS;
2765
2766   if (win == MPI_WIN_NULL)  {
2767     retval = MPI_ERR_WIN;
2768   } else if (name == NULL)  {
2769     retval = MPI_ERR_ARG;
2770   } else {
2771     smpi_mpi_win_get_name(win, name, len);
2772   }
2773   return retval;
2774 }
2775
2776 int PMPI_Win_get_group(MPI_Win  win, MPI_Group * group){
2777   int retval = MPI_SUCCESS;
2778   if (win == MPI_WIN_NULL)  {
2779     retval = MPI_ERR_WIN;
2780   }else {
2781     smpi_mpi_win_get_group(win, group);
2782   }
2783   return retval;
2784 }
2785
2786
2787 int PMPI_Win_fence( int assert,  MPI_Win win){
2788   int retval = 0;
2789   smpi_bench_end();
2790   if (win == MPI_WIN_NULL) {
2791     retval = MPI_ERR_WIN;
2792   } else {
2793   int rank = smpi_process_index();
2794   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2795   retval = smpi_mpi_win_fence(assert, win);
2796   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2797
2798   }
2799   smpi_bench_begin();
2800   return retval;
2801 }
2802
2803 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2804               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2805   int retval = 0;
2806   smpi_bench_end();
2807   if (win == MPI_WIN_NULL) {
2808     retval = MPI_ERR_WIN;
2809   } else if (target_rank == MPI_PROC_NULL) {
2810     retval = MPI_SUCCESS;
2811   } else if (target_rank <0){
2812     retval = MPI_ERR_RANK;
2813   } else if (target_disp <0){
2814       retval = MPI_ERR_ARG;
2815   } else if (origin_count < 0 || target_count < 0) {
2816     retval = MPI_ERR_COUNT;
2817   } else if (origin_addr==NULL && origin_count > 0){
2818     retval = MPI_ERR_COUNT;
2819   } else if ((!is_datatype_valid(origin_datatype)) ||
2820             (!is_datatype_valid(target_datatype))) {
2821     retval = MPI_ERR_TYPE;
2822   } else {
2823     int rank = smpi_process_index();
2824     MPI_Group group;
2825     smpi_mpi_win_get_group(win, &group);
2826     int src_traced = smpi_group_index(group, target_rank);
2827     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, NULL);
2828
2829     retval = smpi_mpi_get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win);
2830
2831     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2832   }
2833   smpi_bench_begin();
2834   return retval;
2835 }
2836
2837 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2838               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2839   int retval = 0;
2840   smpi_bench_end();
2841   if (win == MPI_WIN_NULL) {
2842     retval = MPI_ERR_WIN;
2843   } else if (target_rank == MPI_PROC_NULL) {
2844     retval = MPI_SUCCESS;
2845   } else if (target_rank <0){
2846     retval = MPI_ERR_RANK;
2847   } else if (target_disp <0){
2848     retval = MPI_ERR_ARG;
2849   } else if (origin_count < 0 || target_count < 0) {
2850     retval = MPI_ERR_COUNT;
2851   } else if (origin_addr==NULL && origin_count > 0){
2852     retval = MPI_ERR_COUNT;
2853   } else if ((!is_datatype_valid(origin_datatype)) ||
2854             (!is_datatype_valid(target_datatype))) {
2855     retval = MPI_ERR_TYPE;
2856   } else {
2857     int rank = smpi_process_index();
2858     MPI_Group group;
2859     smpi_mpi_win_get_group(win, &group);
2860     int dst_traced = smpi_group_index(group, target_rank);
2861     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, NULL);
2862     TRACE_smpi_send(rank, rank, dst_traced, origin_count*smpi_datatype_size(origin_datatype));
2863
2864     retval = smpi_mpi_put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win);
2865
2866     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2867   }
2868   smpi_bench_begin();
2869   return retval;
2870 }
2871
2872
2873 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2874               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2875   int retval = 0;
2876   smpi_bench_end();
2877   if (win == MPI_WIN_NULL) {
2878     retval = MPI_ERR_WIN;
2879   } else if (target_rank == MPI_PROC_NULL) {
2880     retval = MPI_SUCCESS;
2881   } else if (target_rank <0){
2882     retval = MPI_ERR_RANK;
2883   } else if (target_disp <0){
2884     retval = MPI_ERR_ARG;
2885   } else if (origin_count < 0 || target_count < 0) {
2886     retval = MPI_ERR_COUNT;
2887   } else if (origin_addr==NULL && origin_count > 0){
2888     retval = MPI_ERR_COUNT;
2889   } else if ((!is_datatype_valid(origin_datatype)) ||
2890             (!is_datatype_valid(target_datatype))) {
2891     retval = MPI_ERR_TYPE;
2892   } else if (op == MPI_OP_NULL) {
2893     retval = MPI_ERR_OP;
2894   } else {
2895     int rank = smpi_process_index();
2896     MPI_Group group;
2897     smpi_mpi_win_get_group(win, &group);
2898     int src_traced = smpi_group_index(group, target_rank);
2899     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, NULL);
2900
2901     retval = smpi_mpi_accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, op, win);
2902
2903     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2904   }
2905   smpi_bench_begin();
2906   return retval;
2907 }
2908
2909
2910 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2911   int retval = 0;
2912   smpi_bench_end();
2913   if (win == MPI_WIN_NULL) {
2914     retval = MPI_ERR_WIN;
2915   } else if (group==MPI_GROUP_NULL){
2916     retval = MPI_ERR_GROUP;
2917   }
2918   else {
2919     int rank = smpi_process_index();
2920     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2921     retval = smpi_mpi_win_post(group,assert,win);
2922     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2923   }
2924   smpi_bench_begin();
2925   return retval;
2926 }
2927
2928 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2929   int retval = 0;
2930   smpi_bench_end();
2931   if (win == MPI_WIN_NULL) {
2932     retval = MPI_ERR_WIN;
2933   } else if (group==MPI_GROUP_NULL){
2934     retval = MPI_ERR_GROUP;
2935   }
2936   else {
2937     int rank = smpi_process_index();
2938     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2939     retval = smpi_mpi_win_start(group,assert,win);
2940     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2941   }
2942   smpi_bench_begin();
2943   return retval;
2944 }
2945
2946
2947 int PMPI_Win_complete(MPI_Win win){
2948   int retval = 0;
2949   smpi_bench_end();
2950   if (win == MPI_WIN_NULL) {
2951     retval = MPI_ERR_WIN;
2952   }
2953   else {
2954     int rank = smpi_process_index();
2955     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2956
2957     retval = smpi_mpi_win_complete(win);
2958
2959     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2960   }
2961   smpi_bench_begin();
2962   return retval;
2963 }
2964
2965 int PMPI_Win_wait(MPI_Win win){
2966   int retval = 0;
2967   smpi_bench_end();
2968   if (win == MPI_WIN_NULL) {
2969     retval = MPI_ERR_WIN;
2970   }
2971   else {
2972     int rank = smpi_process_index();
2973     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2974
2975     retval = smpi_mpi_win_wait(win);
2976
2977     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2978   }
2979   smpi_bench_begin();
2980   return retval;
2981 }
2982
2983 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
2984   void *ptr = xbt_malloc(size);
2985   if(!ptr)
2986     return MPI_ERR_NO_MEM;
2987   else {
2988     *(void **)baseptr = ptr;
2989     return MPI_SUCCESS;
2990   }
2991 }
2992
2993 int PMPI_Free_mem(void *baseptr){
2994   xbt_free(baseptr);
2995   return MPI_SUCCESS;
2996 }
2997
2998 int PMPI_Type_set_name(MPI_Datatype  datatype, char * name)
2999 {
3000   int retval = 0;
3001   if (datatype == MPI_DATATYPE_NULL)  {
3002     retval = MPI_ERR_TYPE;
3003   } else if (name == NULL)  {
3004     retval = MPI_ERR_ARG;
3005   } else {
3006     smpi_datatype_set_name(datatype, name);
3007     retval = MPI_SUCCESS;
3008   }
3009   return retval;
3010 }
3011
3012 int PMPI_Type_get_name(MPI_Datatype  datatype, char * name, int* len)
3013 {
3014   int retval = 0;
3015
3016   if (datatype == MPI_DATATYPE_NULL)  {
3017     retval = MPI_ERR_TYPE;
3018   } else if (name == NULL)  {
3019     retval = MPI_ERR_ARG;
3020   } else {
3021     smpi_datatype_get_name(datatype, name, len);
3022     retval = MPI_SUCCESS;
3023   }
3024   return retval;
3025 }
3026
3027
3028 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
3029   return smpi_type_f2c(datatype);
3030 }
3031
3032 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
3033   return smpi_type_c2f( datatype);
3034 }
3035
3036 MPI_Group PMPI_Group_f2c(MPI_Fint group){
3037   return smpi_group_f2c( group);
3038 }
3039
3040 MPI_Fint PMPI_Group_c2f(MPI_Group group){
3041   return smpi_group_c2f(group);
3042 }
3043
3044 MPI_Request PMPI_Request_f2c(MPI_Fint request){
3045   return smpi_request_f2c(request);
3046 }
3047
3048 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
3049   return smpi_request_c2f(request);
3050 }
3051
3052 MPI_Win PMPI_Win_f2c(MPI_Fint win){
3053   return smpi_win_f2c(win);
3054 }
3055
3056 MPI_Fint PMPI_Win_c2f(MPI_Win win){
3057   return smpi_win_c2f(win);
3058 }
3059
3060 MPI_Op PMPI_Op_f2c(MPI_Fint op){
3061   return smpi_op_f2c(op);
3062 }
3063
3064 MPI_Fint PMPI_Op_c2f(MPI_Op op){
3065   return smpi_op_c2f(op);
3066 }
3067
3068 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
3069   return smpi_comm_f2c(comm);
3070 }
3071
3072 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
3073   return smpi_comm_c2f(comm);
3074 }
3075
3076 MPI_Info PMPI_Info_f2c(MPI_Fint info){
3077   return smpi_info_f2c(info);
3078 }
3079
3080 MPI_Fint PMPI_Info_c2f(MPI_Info info){
3081   return smpi_info_c2f(info);
3082 }
3083
3084 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3085   return smpi_comm_keyval_create(copy_fn, delete_fn, keyval, extra_state);
3086 }
3087
3088 int PMPI_Keyval_free(int* keyval) {
3089   return smpi_comm_keyval_free(keyval);
3090 }
3091
3092 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3093   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO
3094        ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3095        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3096     return MPI_ERR_ARG;
3097   else if (comm==MPI_COMM_NULL)
3098     return MPI_ERR_COMM;
3099   else
3100     return smpi_comm_attr_delete(comm, keyval);
3101 }
3102
3103 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3104   static int one = 1;
3105   static int zero = 0;
3106   static int tag_ub = 1000000;
3107   static int last_used_code = MPI_ERR_LASTCODE;
3108
3109   if (comm==MPI_COMM_NULL){
3110     *flag = 0;
3111     return MPI_ERR_COMM;
3112   }
3113
3114   switch (keyval) {
3115   case MPI_HOST:
3116   case MPI_IO:
3117   case MPI_APPNUM:
3118     *flag = 1;
3119     *(int**)attr_value = &zero;
3120     return MPI_SUCCESS;
3121
3122   case MPI_UNIVERSE_SIZE:
3123     *flag = 1;
3124     *(int**)attr_value = &smpi_universe_size;
3125     return MPI_SUCCESS;
3126
3127   case MPI_LASTUSEDCODE:
3128     *flag = 1;
3129     *(int**)attr_value = &last_used_code;
3130     return MPI_SUCCESS;
3131
3132   case MPI_TAG_UB:
3133     *flag=1;
3134     *(int**)attr_value = &tag_ub;
3135     return MPI_SUCCESS;
3136
3137   case MPI_WTIME_IS_GLOBAL:
3138     *flag = 1;
3139     *(int**)attr_value = &one;
3140     return MPI_SUCCESS;
3141
3142   default:
3143     return smpi_comm_attr_get(comm, keyval, attr_value, flag);
3144   }
3145 }
3146
3147 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3148   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO
3149        ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3150        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3151     return MPI_ERR_ARG;
3152   else if (comm==MPI_COMM_NULL)
3153     return MPI_ERR_COMM;
3154   else
3155   return smpi_comm_attr_put(comm, keyval, attr_value);
3156 }
3157
3158 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3159 {
3160   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3161 }
3162
3163 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3164 {
3165   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3166 }
3167
3168 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3169 {
3170   return PMPI_Attr_delete(comm, comm_keyval);
3171 }
3172
3173 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval, void* extra_state)
3174 {
3175   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3176 }
3177
3178 int PMPI_Comm_free_keyval(int* keyval) {
3179   return PMPI_Keyval_free(keyval);
3180 }
3181
3182
3183 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3184 {
3185   if (type==MPI_DATATYPE_NULL)
3186     return MPI_ERR_TYPE;
3187   else
3188     return smpi_type_attr_get(type, type_keyval, attribute_val, flag);
3189 }
3190
3191 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3192 {
3193   if (type==MPI_DATATYPE_NULL)
3194     return MPI_ERR_TYPE;
3195   else
3196     return smpi_type_attr_put(type, type_keyval, attribute_val);
3197 }
3198
3199 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3200 {
3201   if (type==MPI_DATATYPE_NULL)
3202     return MPI_ERR_TYPE;
3203   else
3204     return smpi_type_attr_delete(type, type_keyval);
3205 }
3206
3207 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state)
3208 {
3209   return smpi_type_keyval_create(copy_fn, delete_fn, keyval, extra_state);
3210 }
3211
3212 int PMPI_Type_free_keyval(int* keyval) {
3213   return smpi_type_keyval_free(keyval);
3214 }
3215
3216 int PMPI_Info_create( MPI_Info *info){
3217   if (info == NULL)
3218     return MPI_ERR_ARG;
3219   *info = xbt_new(s_smpi_mpi_info_t, 1);
3220   (*info)->info_dict= xbt_dict_new_homogeneous(NULL);
3221   (*info)->refcount=1;
3222   return MPI_SUCCESS;
3223 }
3224
3225 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3226   if (info == NULL || key == NULL || value == NULL)
3227     return MPI_ERR_ARG;
3228
3229   xbt_dict_set(info->info_dict, key, (void*)value, NULL);
3230   return MPI_SUCCESS;
3231 }
3232
3233 int PMPI_Info_free( MPI_Info *info){
3234   if (info == NULL || *info==NULL)
3235     return MPI_ERR_ARG;
3236   (*info)->refcount--;
3237   if((*info)->refcount==0){
3238     xbt_dict_free(&((*info)->info_dict));
3239     xbt_free(*info);
3240   }
3241   *info=MPI_INFO_NULL;
3242   return MPI_SUCCESS;
3243 }
3244
3245 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3246   if (info == NULL || key == NULL || valuelen <0)
3247     return MPI_ERR_ARG;
3248   if (value == NULL)
3249     return MPI_ERR_INFO_VALUE;
3250   *flag=FALSE;
3251   char* tmpvalue=(char*)xbt_dict_get_or_null(info->info_dict, key);
3252   if(tmpvalue){
3253     memcpy(value,tmpvalue, (strlen(tmpvalue) + 1 < valuelen) ?
3254                          strlen(tmpvalue) + 1 : valuelen);
3255     *flag=TRUE;
3256   }
3257   return MPI_SUCCESS;
3258 }
3259
3260 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3261   if (info == NULL || newinfo==NULL)
3262     return MPI_ERR_ARG;
3263   *newinfo = xbt_new(s_smpi_mpi_info_t, 1);
3264   (*newinfo)->info_dict= xbt_dict_new_homogeneous(NULL);
3265   xbt_dict_cursor_t cursor = NULL;
3266   int *key;
3267   void* data;
3268   xbt_dict_foreach(info->info_dict,cursor,key,data){
3269     xbt_dict_set((*newinfo)->info_dict, (char*)key, data, NULL);
3270   }
3271   return MPI_SUCCESS;
3272 }
3273
3274 int PMPI_Info_delete(MPI_Info info, char *key){
3275   xbt_ex_t e;
3276   if (info == NULL || key==NULL)
3277     return MPI_ERR_ARG;
3278   TRY {
3279   xbt_dict_remove(info->info_dict, key);
3280   }CATCH(e){
3281     xbt_ex_free(e);
3282     return MPI_ERR_INFO_NOKEY;
3283   }
3284   return MPI_SUCCESS;
3285 }
3286
3287 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3288   if (info == NULL || nkeys==NULL)
3289     return MPI_ERR_ARG;
3290   *nkeys=xbt_dict_size(info->info_dict);
3291   return MPI_SUCCESS;
3292 }
3293
3294 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3295   if (info == NULL || key==NULL || n<0 || n> MPI_MAX_INFO_KEY)
3296     return MPI_ERR_ARG;
3297
3298   xbt_dict_cursor_t cursor = NULL;
3299   char *keyn;
3300   void* data;
3301   int num=0;
3302   xbt_dict_foreach(info->info_dict,cursor,keyn,data){
3303     if(num==n){
3304      strcpy(key,keyn);
3305       return MPI_SUCCESS;
3306     }
3307     num++;
3308   }
3309   return MPI_ERR_ARG;
3310 }
3311
3312 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3313   if (info == NULL || key == NULL || valuelen <0)
3314     return MPI_ERR_ARG;
3315   *flag=FALSE;
3316   char* tmpvalue=(char*)xbt_dict_get_or_null(info->info_dict, key);
3317   if(tmpvalue){
3318     *valuelen=strlen(tmpvalue);
3319     *flag=TRUE;
3320   }
3321   return MPI_SUCCESS;
3322 }
3323
3324 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3325   if(incount<0 || outcount < 0 || inbuf==NULL || outbuf==NULL)
3326     return MPI_ERR_ARG;
3327   if(!is_datatype_valid(type))
3328     return MPI_ERR_TYPE;
3329   if(comm==MPI_COMM_NULL)
3330     return MPI_ERR_COMM;
3331   return smpi_mpi_unpack(inbuf, incount, position, outbuf,outcount,type, comm);
3332 }
3333
3334 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3335   if(incount<0 || outcount < 0|| inbuf==NULL || outbuf==NULL)
3336     return MPI_ERR_ARG;
3337   if(!is_datatype_valid(type))
3338     return MPI_ERR_TYPE;
3339   if(comm==MPI_COMM_NULL)
3340     return MPI_ERR_COMM;
3341   return smpi_mpi_pack(inbuf, incount, type, outbuf,outcount,position, comm);
3342 }
3343
3344 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3345   if(incount<0)
3346     return MPI_ERR_ARG;
3347   if(!is_datatype_valid(datatype))
3348     return MPI_ERR_TYPE;
3349   if(comm==MPI_COMM_NULL)
3350     return MPI_ERR_COMM;
3351
3352   *size=incount*smpi_datatype_size(datatype);
3353
3354   return MPI_SUCCESS;
3355 }
3356
3357
3358 /* The following calls are not yet implemented and will fail at runtime. */
3359 /* Once implemented, please move them above this notice. */
3360
3361 #define NOT_YET_IMPLEMENTED {                                           \
3362     XBT_WARN("Not yet implemented : %s. Please contact the Simgrid team if support is needed", __FUNCTION__); \
3363     return MPI_SUCCESS;                                                 \
3364   }
3365
3366 MPI_Errhandler PMPI_Errhandler_f2c(MPI_Fint errhandler){
3367   NOT_YET_IMPLEMENTED
3368 }
3369
3370 MPI_Fint PMPI_Errhandler_c2f(MPI_Errhandler errhandler){
3371   NOT_YET_IMPLEMENTED
3372 }
3373
3374 int PMPI_Cart_map(MPI_Comm comm_old, int ndims, int* dims, int* periods, int* newrank) {
3375   NOT_YET_IMPLEMENTED
3376 }
3377
3378 int PMPI_Graph_create(MPI_Comm comm_old, int nnodes, int* index, int* edges, int reorder, MPI_Comm* comm_graph) {
3379   NOT_YET_IMPLEMENTED
3380 }
3381
3382 int PMPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int* index, int* edges) {
3383   NOT_YET_IMPLEMENTED
3384 }
3385
3386 int PMPI_Graph_map(MPI_Comm comm_old, int nnodes, int* index, int* edges, int* newrank) {
3387   NOT_YET_IMPLEMENTED
3388 }
3389
3390 int PMPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int* neighbors) {
3391   NOT_YET_IMPLEMENTED
3392 }
3393
3394 int PMPI_Graph_neighbors_count(MPI_Comm comm, int rank, int* nneighbors) {
3395   NOT_YET_IMPLEMENTED
3396 }
3397
3398 int PMPI_Graphdims_get(MPI_Comm comm, int* nnodes, int* nedges) {
3399   NOT_YET_IMPLEMENTED
3400 }
3401
3402 int PMPI_Topo_test(MPI_Comm comm, int* top_type) {
3403   NOT_YET_IMPLEMENTED
3404 }
3405
3406 int PMPI_Errhandler_create(MPI_Handler_function* function, MPI_Errhandler* errhandler) {
3407   NOT_YET_IMPLEMENTED
3408 }
3409
3410 int PMPI_Errhandler_free(MPI_Errhandler* errhandler) {
3411   NOT_YET_IMPLEMENTED
3412 }
3413
3414 int PMPI_Errhandler_get(MPI_Comm comm, MPI_Errhandler* errhandler) {
3415   NOT_YET_IMPLEMENTED
3416 }
3417
3418 int PMPI_Error_string(int errorcode, char* string, int* resultlen) {
3419   NOT_YET_IMPLEMENTED
3420 }
3421
3422 int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler) {
3423   NOT_YET_IMPLEMENTED
3424 }
3425
3426 int PMPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler) {
3427   NOT_YET_IMPLEMENTED
3428 }
3429
3430 int PMPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler) {
3431   NOT_YET_IMPLEMENTED
3432 }
3433
3434 int PMPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler* errhandler) {
3435   NOT_YET_IMPLEMENTED
3436 }
3437
3438 int PMPI_Cancel(MPI_Request* request) {
3439   NOT_YET_IMPLEMENTED
3440 }
3441
3442 int PMPI_Buffer_attach(void* buffer, int size) {
3443   NOT_YET_IMPLEMENTED
3444 }
3445
3446 int PMPI_Buffer_detach(void* buffer, int* size) {
3447   NOT_YET_IMPLEMENTED
3448 }
3449
3450 int PMPI_Comm_test_inter(MPI_Comm comm, int* flag) {
3451   NOT_YET_IMPLEMENTED
3452 }
3453
3454 int PMPI_Pcontrol(const int level )
3455 {
3456   NOT_YET_IMPLEMENTED
3457 }
3458
3459
3460 int PMPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out) {
3461   NOT_YET_IMPLEMENTED
3462 }
3463
3464 int PMPI_Intercomm_merge(MPI_Comm comm, int high, MPI_Comm* comm_out) {
3465   NOT_YET_IMPLEMENTED
3466 }
3467
3468 int PMPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
3469   NOT_YET_IMPLEMENTED
3470 }
3471
3472 int PMPI_Bsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3473   NOT_YET_IMPLEMENTED
3474 }
3475
3476 int PMPI_Ibsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3477   NOT_YET_IMPLEMENTED
3478 }
3479
3480 int PMPI_Comm_remote_group(MPI_Comm comm, MPI_Group* group) {
3481   NOT_YET_IMPLEMENTED
3482 }
3483
3484 int PMPI_Comm_remote_size(MPI_Comm comm, int* size) {
3485   NOT_YET_IMPLEMENTED
3486 }
3487
3488 int PMPI_Rsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
3489   NOT_YET_IMPLEMENTED
3490 }
3491
3492 int PMPI_Rsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3493   NOT_YET_IMPLEMENTED
3494 }
3495
3496 int PMPI_Irsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3497   NOT_YET_IMPLEMENTED
3498 }
3499
3500 int PMPI_Test_cancelled(MPI_Status* status, int* flag) {
3501   NOT_YET_IMPLEMENTED
3502 }
3503
3504
3505
3506 int PMPI_Pack_external_size(char *datarep, int incount, MPI_Datatype datatype, MPI_Aint *size){
3507   NOT_YET_IMPLEMENTED
3508 }
3509
3510 int PMPI_Pack_external(char *datarep, void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, MPI_Aint outcount, MPI_Aint *position){
3511   NOT_YET_IMPLEMENTED
3512 }
3513
3514 int PMPI_Unpack_external( char *datarep, void *inbuf, MPI_Aint insize, MPI_Aint *position, void *outbuf, int outcount, MPI_Datatype datatype){
3515   NOT_YET_IMPLEMENTED
3516 }
3517
3518 int PMPI_Get_elements(MPI_Status* status, MPI_Datatype datatype, int* elements) {
3519   NOT_YET_IMPLEMENTED
3520 }
3521
3522
3523
3524 int PMPI_Type_get_envelope( MPI_Datatype datatype, int *num_integers,
3525                             int *num_addresses, int *num_datatypes, int *combiner){
3526   NOT_YET_IMPLEMENTED
3527 }
3528
3529 int PMPI_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses,
3530                            int max_datatypes, int* array_of_integers, MPI_Aint* array_of_addresses,
3531                            MPI_Datatype* array_of_datatypes){
3532   NOT_YET_IMPLEMENTED
3533 }
3534
3535 int PMPI_Type_create_darray(int size, int rank, int ndims, int* array_of_gsizes,
3536                             int* array_of_distribs, int* array_of_dargs, int* array_of_psizes,
3537                             int order, MPI_Datatype oldtype, MPI_Datatype *newtype) {
3538   NOT_YET_IMPLEMENTED
3539 }
3540
3541 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){
3542   NOT_YET_IMPLEMENTED
3543 }
3544
3545 int PMPI_Type_match_size(int typeclass,int size,MPI_Datatype *datatype){
3546   NOT_YET_IMPLEMENTED
3547 }
3548
3549 int PMPI_Alltoallw( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes,
3550                     void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes,
3551                     MPI_Comm comm){
3552   NOT_YET_IMPLEMENTED
3553 }
3554
3555 int PMPI_Comm_set_name(MPI_Comm comm, char* name){
3556   NOT_YET_IMPLEMENTED
3557 }
3558
3559 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm){
3560   NOT_YET_IMPLEMENTED
3561 }
3562
3563 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm){
3564   NOT_YET_IMPLEMENTED
3565 }
3566
3567 int PMPI_Comm_set_info (MPI_Comm comm, MPI_Info info){
3568   NOT_YET_IMPLEMENTED
3569 }
3570
3571 int PMPI_Comm_get_info (MPI_Comm comm, MPI_Info* info){
3572   NOT_YET_IMPLEMENTED
3573 }
3574
3575 int PMPI_Comm_create_errhandler( MPI_Comm_errhandler_fn *function, MPI_Errhandler *errhandler){
3576   NOT_YET_IMPLEMENTED
3577 }
3578
3579 int PMPI_Add_error_class( int *errorclass){
3580   NOT_YET_IMPLEMENTED
3581 }
3582
3583 int PMPI_Add_error_code(  int errorclass, int *errorcode){
3584   NOT_YET_IMPLEMENTED
3585 }
3586
3587 int PMPI_Add_error_string( int errorcode, char *string){
3588   NOT_YET_IMPLEMENTED
3589 }
3590
3591 int PMPI_Comm_call_errhandler(MPI_Comm comm,int errorcode){
3592   NOT_YET_IMPLEMENTED
3593 }
3594
3595 int PMPI_Request_get_status( MPI_Request request, int *flag, MPI_Status *status){
3596   NOT_YET_IMPLEMENTED
3597 }
3598
3599 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){
3600   NOT_YET_IMPLEMENTED
3601 }
3602
3603 int PMPI_Grequest_complete( MPI_Request request){
3604   NOT_YET_IMPLEMENTED
3605 }
3606
3607 int PMPI_Status_set_cancelled(MPI_Status *status,int flag){
3608   NOT_YET_IMPLEMENTED
3609 }
3610
3611 int PMPI_Status_set_elements( MPI_Status *status, MPI_Datatype datatype, int count){
3612   NOT_YET_IMPLEMENTED
3613 }
3614
3615 int PMPI_Comm_connect( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3616   NOT_YET_IMPLEMENTED
3617 }
3618
3619 int PMPI_Publish_name( char *service_name, MPI_Info info, char *port_name){
3620   NOT_YET_IMPLEMENTED
3621 }
3622
3623 int PMPI_Unpublish_name( char *service_name, MPI_Info info, char *port_name){
3624   NOT_YET_IMPLEMENTED
3625 }
3626
3627 int PMPI_Lookup_name( char *service_name, MPI_Info info, char *port_name){
3628   NOT_YET_IMPLEMENTED
3629 }
3630
3631 int PMPI_Comm_join( int fd, MPI_Comm *intercomm){
3632   NOT_YET_IMPLEMENTED
3633 }
3634
3635 int PMPI_Open_port( MPI_Info info, char *port_name){
3636   NOT_YET_IMPLEMENTED
3637 }
3638
3639 int PMPI_Close_port(char *port_name){
3640   NOT_YET_IMPLEMENTED
3641 }
3642
3643 int PMPI_Comm_accept( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3644   NOT_YET_IMPLEMENTED
3645 }
3646
3647 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){
3648   NOT_YET_IMPLEMENTED
3649 }
3650
3651 int PMPI_Comm_spawn_multiple( int count, char **array_of_commands, char*** array_of_argv,
3652                               int* array_of_maxprocs, MPI_Info* array_of_info, int root,
3653                               MPI_Comm comm, MPI_Comm *intercomm, int* array_of_errcodes){
3654   NOT_YET_IMPLEMENTED
3655 }
3656
3657 int PMPI_Comm_get_parent( MPI_Comm *parent){
3658   NOT_YET_IMPLEMENTED
3659 }
3660
3661 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win) {
3662   NOT_YET_IMPLEMENTED
3663 }
3664
3665 int PMPI_Win_test(MPI_Win win, int *flag){
3666   NOT_YET_IMPLEMENTED
3667 }
3668
3669 int PMPI_Win_unlock(int rank, MPI_Win win){
3670   NOT_YET_IMPLEMENTED
3671 }