Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
modified [PATCH] Privatize data segment for SMPI process and share for MSG process
[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   extra->recvcounts= xbt_malloc(size*sizeof(int));
1824   for(i=0; i< size; i++)//copy data to avoid bad free
1825     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
1826
1827   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1828
1829   smpi_mpi_gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts,
1830                      displs, recvtype, root, comm);
1831     retval = MPI_SUCCESS;
1832   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1833   }
1834
1835   smpi_bench_begin();
1836   return retval;
1837 }
1838
1839 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1840                   void *recvbuf, int recvcount, MPI_Datatype recvtype,
1841                   MPI_Comm comm)
1842 {
1843   int retval = 0;
1844
1845   smpi_bench_end();
1846
1847   if (comm == MPI_COMM_NULL) {
1848     retval = MPI_ERR_COMM;
1849   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1850             (recvtype == MPI_DATATYPE_NULL)){
1851     retval = MPI_ERR_TYPE;
1852   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
1853             (recvcount <0)){
1854     retval = MPI_ERR_COUNT;
1855   } else {
1856     if(sendbuf == MPI_IN_PLACE) {
1857       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*recvcount*smpi_comm_rank(comm);
1858       sendcount=recvcount;
1859       sendtype=recvtype;
1860     }
1861   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1862   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1863   extra->type = TRACING_ALLGATHER;
1864   int known=0;
1865   extra->datatype1 = encode_datatype(sendtype, &known);
1866   int dt_size_send = 1;
1867   if(!known)
1868     dt_size_send = smpi_datatype_size(sendtype);
1869   extra->send_size = sendcount*dt_size_send;
1870   extra->datatype2 = encode_datatype(recvtype, &known);
1871   int dt_size_recv = 1;
1872   if(!known)
1873     dt_size_recv = smpi_datatype_size(recvtype);
1874   extra->recv_size = recvcount*dt_size_recv;
1875
1876   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, extra);
1877
1878   mpi_coll_allgather_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1879                            recvtype, comm);
1880     retval = MPI_SUCCESS;
1881   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1882   }
1883   smpi_bench_begin();
1884   return retval;
1885 }
1886
1887 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1888                    void *recvbuf, int *recvcounts, int *displs,
1889                    MPI_Datatype recvtype, MPI_Comm comm)
1890 {
1891   int retval = 0;
1892
1893   smpi_bench_end();
1894
1895   if (comm == MPI_COMM_NULL) {
1896     retval = MPI_ERR_COMM;
1897   } else if ((( sendbuf != MPI_IN_PLACE) && (sendtype == MPI_DATATYPE_NULL)) ||
1898             (recvtype == MPI_DATATYPE_NULL)){
1899     retval = MPI_ERR_TYPE;
1900   } else if (( sendbuf != MPI_IN_PLACE) && (sendcount <0)){
1901     retval = MPI_ERR_COUNT;
1902   } else if (recvcounts == NULL || displs == NULL) {
1903     retval = MPI_ERR_ARG;
1904   } else {
1905
1906     if(sendbuf == MPI_IN_PLACE) {
1907       sendbuf=((char*)recvbuf)+smpi_datatype_get_extent(recvtype)*displs[smpi_comm_rank(comm)];
1908       sendcount=recvcounts[smpi_comm_rank(comm)];
1909       sendtype=recvtype;
1910     }
1911   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1912   int i=0;
1913   int size = smpi_comm_size(comm);
1914   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1915   extra->type = TRACING_ALLGATHERV;
1916   extra->num_processes = size;
1917   int known=0;
1918   extra->datatype1 = encode_datatype(sendtype, &known);
1919   int dt_size_send = 1;
1920   if(!known)
1921     dt_size_send = smpi_datatype_size(sendtype);
1922   extra->send_size = sendcount*dt_size_send;
1923   extra->datatype2 = encode_datatype(recvtype, &known);
1924   int dt_size_recv = 1;
1925   if(!known)
1926     dt_size_recv = smpi_datatype_size(recvtype);
1927   extra->recvcounts= xbt_malloc(size*sizeof(int));
1928   for(i=0; i< size; i++)//copy data to avoid bad free
1929     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
1930
1931   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
1932
1933     mpi_coll_allgatherv_fun(sendbuf, sendcount, sendtype, recvbuf, recvcounts,
1934                         displs, recvtype, comm);
1935     retval = MPI_SUCCESS;
1936   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
1937   }
1938
1939   smpi_bench_begin();
1940   return retval;
1941 }
1942
1943 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
1944                 void *recvbuf, int recvcount, MPI_Datatype recvtype,
1945                 int root, MPI_Comm comm)
1946 {
1947   int retval = 0;
1948
1949   smpi_bench_end();
1950
1951   if (comm == MPI_COMM_NULL) {
1952     retval = MPI_ERR_COMM;
1953   } else if (((smpi_comm_rank(comm)==root) && (!is_datatype_valid(sendtype)))
1954              || ((recvbuf !=MPI_IN_PLACE) && (!is_datatype_valid(recvtype)))){
1955     retval = MPI_ERR_TYPE;
1956   } else if ((sendbuf == recvbuf) ||
1957       ((smpi_comm_rank(comm)==root) && sendcount>0 && (sendbuf == NULL))){
1958     retval = MPI_ERR_BUFFER;
1959   }else {
1960
1961     if (recvbuf == MPI_IN_PLACE) {
1962         recvtype=sendtype;
1963         recvcount=sendcount;
1964     }
1965   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
1966   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
1967   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
1968   extra->type = TRACING_SCATTER;
1969   extra->root = root_traced;
1970   int known=0;
1971   extra->datatype1 = encode_datatype(sendtype, &known);
1972   int dt_size_send = 1;
1973   if((smpi_comm_rank(comm)==root) && !known)
1974     dt_size_send = smpi_datatype_size(sendtype);
1975   extra->send_size = sendcount*dt_size_send;
1976   extra->datatype2 = encode_datatype(recvtype, &known);
1977   int dt_size_recv = 1;
1978   if(!known)
1979     dt_size_recv = smpi_datatype_size(recvtype);
1980   extra->recv_size = recvcount*dt_size_recv;
1981   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
1982
1983   mpi_coll_scatter_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount,
1984                      recvtype, root, comm);
1985     retval = MPI_SUCCESS;
1986   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
1987   }
1988
1989   smpi_bench_begin();
1990   return retval;
1991 }
1992
1993 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
1994                  MPI_Datatype sendtype, void *recvbuf, int recvcount,
1995                  MPI_Datatype recvtype, int root, MPI_Comm comm)
1996 {
1997   int retval = 0;
1998
1999   smpi_bench_end();
2000
2001   if (comm == MPI_COMM_NULL) {
2002     retval = MPI_ERR_COMM;
2003   } else if (sendcounts == NULL || displs == NULL) {
2004     retval = MPI_ERR_ARG;
2005   } else if (((smpi_comm_rank(comm)==root) && (sendtype == MPI_DATATYPE_NULL))
2006              || ((recvbuf !=MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
2007     retval = MPI_ERR_TYPE;
2008   } else {
2009     if (recvbuf == MPI_IN_PLACE) {
2010         recvtype=sendtype;
2011         recvcount=sendcounts[smpi_comm_rank(comm)];
2012     }
2013   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2014   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2015   int i=0;
2016   int size = smpi_comm_size(comm);
2017   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2018   extra->type = TRACING_SCATTERV;
2019   extra->num_processes = size;
2020   extra->root = root_traced;
2021   int known=0;
2022   extra->datatype1 = encode_datatype(sendtype, &known);
2023   int dt_size_send = 1;
2024   if(!known)
2025     dt_size_send = smpi_datatype_size(sendtype);
2026   extra->sendcounts= xbt_malloc(size*sizeof(int));
2027   for(i=0; i< size; i++)//copy data to avoid bad free
2028     extra->sendcounts[i] = sendcounts[i]*dt_size_send;
2029   extra->datatype2 = encode_datatype(recvtype, &known);
2030   int dt_size_recv = 1;
2031   if(!known)
2032     dt_size_recv = smpi_datatype_size(recvtype);
2033   extra->recv_size = recvcount*dt_size_recv;
2034   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2035
2036     smpi_mpi_scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf,
2037                       recvcount, recvtype, root, comm);
2038
2039     retval = MPI_SUCCESS;
2040   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2041   }
2042
2043   smpi_bench_begin();
2044   return retval;
2045 }
2046
2047 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count,
2048                MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
2049 {
2050   int retval = 0;
2051
2052   smpi_bench_end();
2053
2054   if (comm == MPI_COMM_NULL) {
2055     retval = MPI_ERR_COMM;
2056   } else if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2057     retval = MPI_ERR_ARG;
2058   } else {
2059   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2060   int root_traced = smpi_group_index(smpi_comm_group(comm), root);
2061   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2062   extra->type = TRACING_REDUCE;
2063   int known=0;
2064   extra->datatype1 = encode_datatype(datatype, &known);
2065   int dt_size_send = 1;
2066   if(!known)
2067     dt_size_send = smpi_datatype_size(datatype);
2068   extra->send_size = count*dt_size_send;
2069   extra->root = root_traced;
2070
2071   TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__,extra);
2072
2073   mpi_coll_reduce_fun(sendbuf, recvbuf, count, datatype, op, root, comm);
2074
2075     retval = MPI_SUCCESS;
2076   TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
2077   }
2078
2079   smpi_bench_begin();
2080   return retval;
2081 }
2082
2083 int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count,
2084     MPI_Datatype datatype, MPI_Op op){
2085   int retval = 0;
2086
2087     smpi_bench_end();
2088     if (!is_datatype_valid(datatype) || op == MPI_OP_NULL) {
2089       retval = MPI_ERR_ARG;
2090     } else {
2091       smpi_op_apply(op, inbuf, inoutbuf, &count, &datatype);
2092       retval=MPI_SUCCESS;
2093     }
2094     smpi_bench_begin();
2095     return retval;
2096 }
2097
2098 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count,
2099                   MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2100 {
2101   int retval = 0;
2102
2103   smpi_bench_end();
2104
2105   if (comm == MPI_COMM_NULL) {
2106     retval = MPI_ERR_COMM;
2107   } else if (!is_datatype_valid(datatype)) {
2108     retval = MPI_ERR_TYPE;
2109   } else if (op == MPI_OP_NULL) {
2110     retval = MPI_ERR_OP;
2111   } else {
2112
2113     char* sendtmpbuf = (char*) sendbuf;
2114     if( sendbuf == MPI_IN_PLACE ) {
2115       sendtmpbuf = (char *)xbt_malloc(count*smpi_datatype_get_extent(datatype));
2116       smpi_datatype_copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
2117     }
2118   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2119   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2120   extra->type = TRACING_ALLREDUCE;
2121   int known=0;
2122   extra->datatype1 = encode_datatype(datatype, &known);
2123   int dt_size_send = 1;
2124   if(!known)
2125     dt_size_send = smpi_datatype_size(datatype);
2126   extra->send_size = count*dt_size_send;
2127
2128   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2129
2130   mpi_coll_allreduce_fun(sendtmpbuf, recvbuf, count, datatype, op, comm);
2131
2132     if( sendbuf == MPI_IN_PLACE )
2133       xbt_free(sendtmpbuf);
2134
2135     retval = MPI_SUCCESS;
2136   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2137   }
2138
2139   smpi_bench_begin();
2140   return retval;
2141 }
2142
2143 int PMPI_Scan(void *sendbuf, void *recvbuf, int count,
2144              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2145 {
2146   int retval = 0;
2147
2148   smpi_bench_end();
2149
2150   if (comm == MPI_COMM_NULL) {
2151     retval = MPI_ERR_COMM;
2152   } else if (!is_datatype_valid(datatype)) {
2153     retval = MPI_ERR_TYPE;
2154   } else if (op == MPI_OP_NULL) {
2155     retval = MPI_ERR_OP;
2156   } else {
2157   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2158   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2159   extra->type = TRACING_SCAN;
2160   int known=0;
2161   extra->datatype1 = encode_datatype(datatype, &known);
2162   int dt_size_send = 1;
2163   if(!known)
2164     dt_size_send = smpi_datatype_size(datatype);
2165   extra->send_size = count*dt_size_send;
2166
2167   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2168
2169   smpi_mpi_scan(sendbuf, recvbuf, count, datatype, op, comm);
2170
2171   retval = MPI_SUCCESS;
2172   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2173   }
2174
2175   smpi_bench_begin();
2176   return retval;
2177 }
2178
2179 int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
2180                 MPI_Op op, MPI_Comm comm){
2181   int retval = 0;
2182
2183   smpi_bench_end();
2184
2185   if (comm == MPI_COMM_NULL) {
2186     retval = MPI_ERR_COMM;
2187   } else if (!is_datatype_valid(datatype)) {
2188     retval = MPI_ERR_TYPE;
2189   } else if (op == MPI_OP_NULL) {
2190     retval = MPI_ERR_OP;
2191   } else {
2192   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2193   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2194   extra->type = TRACING_EXSCAN;
2195   int known=0;
2196   extra->datatype1 = encode_datatype(datatype, &known);
2197   int dt_size_send = 1;
2198   if(!known)
2199     dt_size_send = smpi_datatype_size(datatype);
2200   extra->send_size = count*dt_size_send;
2201   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2202
2203   smpi_mpi_exscan(sendbuf, recvbuf, count, datatype, op, comm);
2204     retval = MPI_SUCCESS;
2205   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2206   }
2207
2208   smpi_bench_begin();
2209   return retval;
2210 }
2211
2212 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
2213                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2214 {
2215   int retval = 0;
2216   smpi_bench_end();
2217
2218   if (comm == MPI_COMM_NULL) {
2219     retval = MPI_ERR_COMM;
2220   } else if (!is_datatype_valid(datatype)) {
2221     retval = MPI_ERR_TYPE;
2222   } else if (op == MPI_OP_NULL) {
2223     retval = MPI_ERR_OP;
2224   } else if (recvcounts == NULL) {
2225     retval = MPI_ERR_ARG;
2226   } else {
2227   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2228   int i=0;
2229   int size = smpi_comm_size(comm);
2230   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2231   extra->type = TRACING_REDUCE_SCATTER;
2232   extra->num_processes = size;
2233   int known=0;
2234   extra->datatype1 = encode_datatype(datatype, &known);
2235   int dt_size_send = 1;
2236   if(!known)
2237     dt_size_send = smpi_datatype_size(datatype);
2238   extra->send_size = 0;
2239   extra->recvcounts= xbt_malloc(size*sizeof(int));
2240   for(i=0; i< size; i++)//copy data to avoid bad free
2241     extra->recvcounts[i] = recvcounts[i]*dt_size_send;
2242   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2243
2244   void* sendtmpbuf=sendbuf;
2245     if(sendbuf==MPI_IN_PLACE)
2246       sendtmpbuf=recvbuf;
2247
2248     mpi_coll_reduce_scatter_fun(sendtmpbuf, recvbuf, recvcounts,
2249                        datatype,  op, comm);
2250     retval = MPI_SUCCESS;
2251   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2252   }
2253
2254   smpi_bench_begin();
2255   return retval;
2256 }
2257
2258 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
2259                        MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
2260 {
2261   int retval,i;
2262   smpi_bench_end();
2263
2264   if (comm == MPI_COMM_NULL) {
2265     retval = MPI_ERR_COMM;
2266   } else if (!is_datatype_valid(datatype)) {
2267     retval = MPI_ERR_TYPE;
2268   } else if (op == MPI_OP_NULL) {
2269     retval = MPI_ERR_OP;
2270   } else if (recvcount < 0) {
2271     retval = MPI_ERR_ARG;
2272   } else {
2273     int count=smpi_comm_size(comm);
2274
2275   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2276   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2277   extra->type = TRACING_REDUCE_SCATTER;
2278   extra->num_processes = count;
2279   int known=0;
2280   extra->datatype1 = encode_datatype(datatype, &known);
2281   int dt_size_send = 1;
2282   if(!known)
2283     dt_size_send = smpi_datatype_size(datatype);
2284   extra->send_size = 0;
2285   extra->recvcounts= xbt_malloc(count*sizeof(int));
2286   for(i=0; i< count; i++)//copy data to avoid bad free
2287     extra->recvcounts[i] = recvcount*dt_size_send;
2288
2289   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2290
2291   int* recvcounts=(int*)xbt_malloc(count);
2292     for (i=0; i<count;i++)recvcounts[i]=recvcount;
2293     mpi_coll_reduce_scatter_fun(sendbuf, recvbuf, recvcounts,
2294                        datatype,  op, comm);
2295     xbt_free(recvcounts);
2296     retval = MPI_SUCCESS;
2297
2298     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2299   }
2300
2301   smpi_bench_begin();
2302   return retval;
2303 }
2304
2305 int PMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
2306                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
2307                  MPI_Comm comm)
2308 {
2309   int retval = 0;
2310
2311   smpi_bench_end();
2312
2313   if (comm == MPI_COMM_NULL) {
2314     retval = MPI_ERR_COMM;
2315   } else if (sendtype == MPI_DATATYPE_NULL
2316              || recvtype == MPI_DATATYPE_NULL) {
2317     retval = MPI_ERR_TYPE;
2318   } else {
2319   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2320   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2321   extra->type = TRACING_ALLTOALL;
2322   int known=0;
2323   extra->datatype1 = encode_datatype(sendtype, &known);
2324   if(!known)
2325     extra->send_size = sendcount*smpi_datatype_size(sendtype);
2326   else
2327     extra->send_size = sendcount;
2328   extra->datatype2 = encode_datatype(recvtype, &known);
2329   if(!known)
2330     extra->recv_size = recvcount*smpi_datatype_size(recvtype);
2331   else
2332     extra->recv_size = recvcount;
2333   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2334
2335   retval = mpi_coll_alltoall_fun(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
2336
2337   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2338   }
2339
2340   smpi_bench_begin();
2341   return retval;
2342 }
2343
2344 int PMPI_Alltoallv(void *sendbuf, int *sendcounts, int *senddisps,
2345                   MPI_Datatype sendtype, void *recvbuf, int *recvcounts,
2346                   int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
2347 {
2348   int retval = 0;
2349
2350   smpi_bench_end();
2351
2352   if (comm == MPI_COMM_NULL) {
2353     retval = MPI_ERR_COMM;
2354   } else if (sendtype == MPI_DATATYPE_NULL
2355              || recvtype == MPI_DATATYPE_NULL) {
2356     retval = MPI_ERR_TYPE;
2357   } else if (sendcounts == NULL || senddisps == NULL || recvcounts == NULL
2358              || recvdisps == NULL) {
2359     retval = MPI_ERR_ARG;
2360   } else {
2361   int rank = comm != MPI_COMM_NULL ? smpi_process_index() : -1;
2362   int i=0;
2363   int size = smpi_comm_size(comm);
2364   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
2365   extra->type = TRACING_ALLTOALLV;
2366   extra->send_size = 0;
2367   extra->recv_size = 0;
2368   extra->recvcounts= xbt_malloc(size*sizeof(int));
2369   extra->sendcounts= xbt_malloc(size*sizeof(int));
2370   int known=0;
2371   extra->datatype1 = encode_datatype(sendtype, &known);
2372   int dt_size_send = 1;
2373   if(!known)
2374     dt_size_send = smpi_datatype_size(sendtype);
2375   int dt_size_recv = 1;
2376   extra->datatype2 = encode_datatype(recvtype, &known);
2377   if(!known)
2378     dt_size_recv = smpi_datatype_size(recvtype);
2379   for(i=0; i< size; i++){//copy data to avoid bad free
2380     extra->send_size += sendcounts[i]*dt_size_send;
2381     extra->recv_size += recvcounts[i]*dt_size_recv;
2382
2383     extra->sendcounts[i] = sendcounts[i]*dt_size_send;
2384     extra->recvcounts[i] = recvcounts[i]*dt_size_recv;
2385   }
2386   extra->num_processes = size;
2387   TRACE_smpi_collective_in(rank, -1, __FUNCTION__,extra);
2388
2389   retval =
2390         mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps, sendtype,
2391                                   recvbuf, recvcounts, recvdisps, recvtype,
2392                                   comm);
2393   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2394   }
2395
2396   smpi_bench_begin();
2397   return retval;
2398 }
2399
2400
2401 int PMPI_Get_processor_name(char *name, int *resultlen)
2402 {
2403   int retval = MPI_SUCCESS;
2404
2405   strncpy(name, SIMIX_host_get_name(SIMIX_host_self()),
2406           strlen(SIMIX_host_get_name(SIMIX_host_self())) < MPI_MAX_PROCESSOR_NAME - 1 ?
2407           strlen(SIMIX_host_get_name(SIMIX_host_self())) +1 :
2408           MPI_MAX_PROCESSOR_NAME - 1 );
2409   *resultlen =
2410       strlen(name) >
2411       MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
2412
2413   return retval;
2414 }
2415
2416 int PMPI_Get_count(MPI_Status * status, MPI_Datatype datatype, int *count)
2417 {
2418   int retval = MPI_SUCCESS;
2419   size_t size;
2420
2421   if (status == NULL || count == NULL) {
2422     retval = MPI_ERR_ARG;
2423   } else if (!is_datatype_valid(datatype)) {
2424     retval = MPI_ERR_TYPE;
2425   } else {
2426     size = smpi_datatype_size(datatype);
2427     if (size == 0) {
2428       *count = 0;
2429     } else if (status->count % size != 0) {
2430       retval = MPI_UNDEFINED;
2431     } else {
2432       *count = smpi_mpi_get_count(status, datatype);
2433     }
2434   }
2435   return retval;
2436 }
2437
2438 int PMPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type) {
2439   int retval = 0;
2440
2441   if (old_type == MPI_DATATYPE_NULL) {
2442     retval = MPI_ERR_TYPE;
2443   } else if (count<0){
2444     retval = MPI_ERR_COUNT;
2445   } else {
2446     retval = smpi_datatype_contiguous(count, old_type, new_type, 0);
2447   }
2448   return retval;
2449 }
2450
2451 int PMPI_Type_commit(MPI_Datatype* datatype) {
2452   int retval = 0;
2453
2454   if (datatype == NULL || *datatype == MPI_DATATYPE_NULL) {
2455     retval = MPI_ERR_TYPE;
2456   } else {
2457     smpi_datatype_commit(datatype);
2458     retval = MPI_SUCCESS;
2459   }
2460   return retval;
2461 }
2462
2463
2464 int PMPI_Type_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2465   int retval = 0;
2466
2467   if (old_type == MPI_DATATYPE_NULL) {
2468     retval = MPI_ERR_TYPE;
2469   } else if (count<0 || blocklen<0){
2470     retval = MPI_ERR_COUNT;
2471   } else {
2472     retval = smpi_datatype_vector(count, blocklen, stride, old_type, new_type);
2473   }
2474   return retval;
2475 }
2476
2477 int PMPI_Type_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2478   int retval = 0;
2479
2480   if (old_type == MPI_DATATYPE_NULL) {
2481     retval = MPI_ERR_TYPE;
2482   } else if (count<0 || blocklen<0){
2483     retval = MPI_ERR_COUNT;
2484   } else {
2485     retval = smpi_datatype_hvector(count, blocklen, stride, old_type, new_type);
2486   }
2487   return retval;
2488 }
2489
2490 int PMPI_Type_create_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type) {
2491   return MPI_Type_hvector(count, blocklen, stride, old_type, new_type);
2492 }
2493
2494 int PMPI_Type_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2495   int retval = 0;
2496
2497   if (old_type == MPI_DATATYPE_NULL) {
2498     retval = MPI_ERR_TYPE;
2499   } else if (count<0){
2500     retval = MPI_ERR_COUNT;
2501   } else {
2502     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2503   }
2504   return retval;
2505 }
2506
2507 int PMPI_Type_create_indexed(int count, int* blocklens, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2508   int retval = 0;
2509
2510   if (old_type == MPI_DATATYPE_NULL) {
2511     retval = MPI_ERR_TYPE;
2512   } else if (count<0){
2513     retval = MPI_ERR_COUNT;
2514   } else {
2515     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2516   }
2517   return retval;
2518 }
2519
2520 int PMPI_Type_create_indexed_block(int count, int blocklength, int* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2521   int retval,i;
2522
2523   if (old_type == MPI_DATATYPE_NULL) {
2524     retval = MPI_ERR_TYPE;
2525   } else if (count<0){
2526     retval = MPI_ERR_COUNT;
2527   } else {
2528     int* blocklens=(int*)xbt_malloc(blocklength*count);
2529     for (i=0; i<count;i++)blocklens[i]=blocklength;
2530     retval = smpi_datatype_indexed(count, blocklens, indices, old_type, new_type);
2531     xbt_free(blocklens);
2532   }
2533   return retval;
2534 }
2535
2536
2537 int PMPI_Type_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2538   int retval = 0;
2539
2540   if (old_type == MPI_DATATYPE_NULL) {
2541     retval = MPI_ERR_TYPE;
2542   } else if (count<0){
2543     retval = MPI_ERR_COUNT;
2544   } else {
2545     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2546   }
2547   return retval;
2548 }
2549
2550 int PMPI_Type_create_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2551   return PMPI_Type_hindexed(count, blocklens,indices,old_type,new_type);
2552 }
2553
2554 int PMPI_Type_create_hindexed_block(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* new_type) {
2555   int retval,i;
2556
2557   if (old_type == MPI_DATATYPE_NULL) {
2558     retval = MPI_ERR_TYPE;
2559   } else if (count<0){
2560     retval = MPI_ERR_COUNT;
2561   } else {
2562     int* blocklens=(int*)xbt_malloc(blocklength*count);
2563     for (i=0; i<count;i++)blocklens[i]=blocklength;
2564     retval = smpi_datatype_hindexed(count, blocklens, indices, old_type, new_type);
2565     xbt_free(blocklens);
2566   }
2567   return retval;
2568 }
2569
2570
2571 int PMPI_Type_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2572   int retval = 0;
2573
2574   if (count<0){
2575     retval = MPI_ERR_COUNT;
2576   } else {
2577     retval = smpi_datatype_struct(count, blocklens, indices, old_types, new_type);
2578   }
2579   return retval;
2580 }
2581
2582 int PMPI_Type_create_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datatype* old_types, MPI_Datatype* new_type) {
2583   return PMPI_Type_struct(count, blocklens, indices, old_types, new_type);
2584 }
2585
2586
2587 int PMPI_Error_class(int errorcode, int* errorclass) {
2588   // assume smpi uses only standard mpi error codes
2589   *errorclass=errorcode;
2590   return MPI_SUCCESS;
2591 }
2592
2593
2594 int PMPI_Initialized(int* flag) {
2595    *flag=smpi_process_initialized();
2596    return MPI_SUCCESS;
2597 }
2598
2599 /* The topo part of MPI_COMM_WORLD should always be NULL. When other topologies
2600  * will be implemented, not only should we check if the topology is NULL, but
2601  * we should check if it is the good topology type (so we have to add a
2602  *  MPIR_Topo_Type field, and replace the MPI_Topology field by an union)*/
2603
2604 int PMPI_Cart_create(MPI_Comm comm_old, int ndims, int* dims, int* periodic, int reorder, MPI_Comm* comm_cart) {
2605   int retval = 0;
2606   if (comm_old == MPI_COMM_NULL){
2607     retval =  MPI_ERR_COMM;
2608   } else if (ndims < 0 ||
2609            (ndims > 0 && (dims == NULL ||
2610                           periodic == NULL)) ||
2611            comm_cart == NULL) {
2612     retval = MPI_ERR_ARG;
2613   } else{
2614     retval = smpi_mpi_cart_create(comm_old, ndims, dims, periodic, reorder, comm_cart);
2615   }
2616   return retval;
2617 }
2618
2619 int PMPI_Cart_rank(MPI_Comm comm, int* coords, int* rank) {
2620   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2621     return MPI_ERR_TOPOLOGY;
2622   }
2623   if (coords == NULL) {
2624     return MPI_ERR_ARG;
2625   }
2626   return smpi_mpi_cart_rank(comm, coords, rank);
2627 }
2628
2629 int PMPI_Cart_shift(MPI_Comm comm, int direction, int displ, int* source, int* dest) {
2630   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2631     return MPI_ERR_TOPOLOGY;
2632   }
2633   if (source == NULL || dest == NULL || direction < 0 ) {
2634     return MPI_ERR_ARG;
2635   }
2636   return smpi_mpi_cart_shift(comm, direction, displ, source, dest);
2637 }
2638
2639 int PMPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int* coords) {
2640   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2641     return MPI_ERR_TOPOLOGY;
2642   }
2643   if (rank < 0 || rank >= smpi_comm_size(comm)) {
2644     return MPI_ERR_RANK;
2645   }
2646   if (maxdims <= 0) {
2647     return MPI_ERR_ARG;
2648   }
2649   if(coords == NULL) {
2650     return MPI_ERR_ARG;
2651   }
2652   return smpi_mpi_cart_coords(comm, rank, maxdims, coords);
2653 }
2654
2655 int PMPI_Cart_get(MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords) {
2656   if(comm == NULL || smpi_comm_topo(comm) == NULL) {
2657     return MPI_ERR_TOPOLOGY;
2658   }
2659   if(maxdims <= 0 || dims == NULL || periods == NULL || coords == NULL) {
2660     return MPI_ERR_ARG;
2661   }
2662   return smpi_mpi_cart_get(comm, maxdims, dims, periods, coords);
2663 }
2664
2665 int PMPI_Cartdim_get(MPI_Comm comm, int* ndims) {
2666   if (comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2667     return MPI_ERR_TOPOLOGY;
2668   }
2669   if (ndims == NULL) {
2670     return MPI_ERR_ARG;
2671   }
2672   return smpi_mpi_cartdim_get(comm, ndims);
2673 }
2674
2675 int PMPI_Dims_create(int nnodes, int ndims, int* dims) {
2676   if(dims == NULL) {
2677     return MPI_ERR_ARG;
2678   }
2679   if (ndims < 1 || nnodes < 1) {
2680     return MPI_ERR_DIMS;
2681   }
2682
2683   return smpi_mpi_dims_create(nnodes, ndims, dims);
2684 }
2685
2686 int PMPI_Cart_sub(MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new) {
2687   if(comm == MPI_COMM_NULL || smpi_comm_topo(comm) == NULL) {
2688     return MPI_ERR_TOPOLOGY;
2689   }
2690   if (comm_new == NULL) {
2691     return MPI_ERR_ARG;
2692   }
2693   return smpi_mpi_cart_sub(comm, remain_dims, comm_new);
2694 }
2695
2696 int PMPI_Type_create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
2697     if(oldtype == MPI_DATATYPE_NULL) {
2698         return MPI_ERR_TYPE;
2699     }
2700     int blocks[3] = { 1, 1, 1 };
2701     MPI_Aint disps[3] = { lb, 0, lb+extent };
2702     MPI_Datatype types[3] = { MPI_LB, oldtype, MPI_UB };
2703
2704     s_smpi_mpi_struct_t* subtype = smpi_datatype_struct_create( blocks,
2705                                                                 disps,
2706                                                                 3,
2707                                                                 types
2708                                                                 );
2709     smpi_datatype_create(newtype,oldtype->size, lb, lb + extent, 1 , subtype, DT_FLAG_VECTOR);
2710
2711     (*newtype)->flags &= ~DT_FLAG_COMMITED;
2712     return MPI_SUCCESS;
2713 }
2714
2715
2716
2717 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
2718   int retval = 0;
2719   smpi_bench_end();
2720   if (comm == MPI_COMM_NULL) {
2721     retval= MPI_ERR_COMM;
2722   }else if ((base == NULL && size != 0)
2723             || disp_unit <= 0 || size < 0 ){
2724     retval= MPI_ERR_OTHER;
2725   }else{
2726     *win = smpi_mpi_win_create( base, size, disp_unit, info, comm);
2727     retval = MPI_SUCCESS;
2728   }
2729   smpi_bench_begin();
2730   return retval;
2731 }
2732
2733 int PMPI_Win_free( MPI_Win* win){
2734   int retval = 0;
2735   smpi_bench_end();
2736   if (win == NULL || *win == MPI_WIN_NULL) {
2737     retval = MPI_ERR_WIN;
2738   }else{
2739     retval=smpi_mpi_win_free(win);
2740   }
2741   smpi_bench_begin();
2742   return retval;
2743 }
2744
2745 int PMPI_Win_set_name(MPI_Win  win, char * name)
2746 {
2747   int retval = 0;
2748   if (win == MPI_WIN_NULL)  {
2749     retval = MPI_ERR_TYPE;
2750   } else if (name == NULL)  {
2751     retval = MPI_ERR_ARG;
2752   } else {
2753     smpi_mpi_win_set_name(win, name);
2754     retval = MPI_SUCCESS;
2755   }
2756   return retval;
2757 }
2758
2759 int PMPI_Win_get_name(MPI_Win  win, char * name, int* len)
2760 {
2761   int retval = MPI_SUCCESS;
2762
2763   if (win == MPI_WIN_NULL)  {
2764     retval = MPI_ERR_WIN;
2765   } else if (name == NULL)  {
2766     retval = MPI_ERR_ARG;
2767   } else {
2768     smpi_mpi_win_get_name(win, name, len);
2769   }
2770   return retval;
2771 }
2772
2773 int PMPI_Win_get_group(MPI_Win  win, MPI_Group * group){
2774   int retval = MPI_SUCCESS;
2775   if (win == MPI_WIN_NULL)  {
2776     retval = MPI_ERR_WIN;
2777   }else {
2778     smpi_mpi_win_get_group(win, group);
2779   }
2780   return retval;
2781 }
2782
2783
2784 int PMPI_Win_fence( int assert,  MPI_Win win){
2785   int retval = 0;
2786   smpi_bench_end();
2787   if (win == MPI_WIN_NULL) {
2788     retval = MPI_ERR_WIN;
2789   } else {
2790   int rank = smpi_process_index();
2791   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2792   retval = smpi_mpi_win_fence(assert, win);
2793   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2794
2795   }
2796   smpi_bench_begin();
2797   return retval;
2798 }
2799
2800 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2801               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2802   int retval = 0;
2803   smpi_bench_end();
2804   if (win == MPI_WIN_NULL) {
2805     retval = MPI_ERR_WIN;
2806   } else if (target_rank == MPI_PROC_NULL) {
2807     retval = MPI_SUCCESS;
2808   } else if (target_rank <0){
2809     retval = MPI_ERR_RANK;
2810   } else if (target_disp <0){
2811       retval = MPI_ERR_ARG;
2812   } else if (origin_count < 0 || target_count < 0) {
2813     retval = MPI_ERR_COUNT;
2814   } else if (origin_addr==NULL && origin_count > 0){
2815     retval = MPI_ERR_COUNT;
2816   } else if ((!is_datatype_valid(origin_datatype)) ||
2817             (!is_datatype_valid(target_datatype))) {
2818     retval = MPI_ERR_TYPE;
2819   } else {
2820     int rank = smpi_process_index();
2821     MPI_Group group;
2822     smpi_mpi_win_get_group(win, &group);
2823     int src_traced = smpi_group_index(group, target_rank);
2824     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, NULL);
2825
2826     retval = smpi_mpi_get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win);
2827
2828     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2829   }
2830   smpi_bench_begin();
2831   return retval;
2832 }
2833
2834 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2835               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
2836   int retval = 0;
2837   smpi_bench_end();
2838   if (win == MPI_WIN_NULL) {
2839     retval = MPI_ERR_WIN;
2840   } else if (target_rank == MPI_PROC_NULL) {
2841     retval = MPI_SUCCESS;
2842   } else if (target_rank <0){
2843     retval = MPI_ERR_RANK;
2844   } else if (target_disp <0){
2845     retval = MPI_ERR_ARG;
2846   } else if (origin_count < 0 || target_count < 0) {
2847     retval = MPI_ERR_COUNT;
2848   } else if (origin_addr==NULL && origin_count > 0){
2849     retval = MPI_ERR_COUNT;
2850   } else if ((!is_datatype_valid(origin_datatype)) ||
2851             (!is_datatype_valid(target_datatype))) {
2852     retval = MPI_ERR_TYPE;
2853   } else {
2854     int rank = smpi_process_index();
2855     MPI_Group group;
2856     smpi_mpi_win_get_group(win, &group);
2857     int dst_traced = smpi_group_index(group, target_rank);
2858     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, NULL);
2859     TRACE_smpi_send(rank, rank, dst_traced, origin_count*smpi_datatype_size(origin_datatype));
2860
2861     retval = smpi_mpi_put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, win);
2862
2863     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
2864   }
2865   smpi_bench_begin();
2866   return retval;
2867 }
2868
2869
2870 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
2871               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
2872   int retval = 0;
2873   smpi_bench_end();
2874   if (win == MPI_WIN_NULL) {
2875     retval = MPI_ERR_WIN;
2876   } else if (target_rank == MPI_PROC_NULL) {
2877     retval = MPI_SUCCESS;
2878   } else if (target_rank <0){
2879     retval = MPI_ERR_RANK;
2880   } else if (target_disp <0){
2881     retval = MPI_ERR_ARG;
2882   } else if (origin_count < 0 || target_count < 0) {
2883     retval = MPI_ERR_COUNT;
2884   } else if (origin_addr==NULL && origin_count > 0){
2885     retval = MPI_ERR_COUNT;
2886   } else if ((!is_datatype_valid(origin_datatype)) ||
2887             (!is_datatype_valid(target_datatype))) {
2888     retval = MPI_ERR_TYPE;
2889   } else if (op == MPI_OP_NULL) {
2890     retval = MPI_ERR_OP;
2891   } else {
2892     int rank = smpi_process_index();
2893     MPI_Group group;
2894     smpi_mpi_win_get_group(win, &group);
2895     int src_traced = smpi_group_index(group, target_rank);
2896     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, NULL);
2897
2898     retval = smpi_mpi_accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count, target_datatype, op, win);
2899
2900     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
2901   }
2902   smpi_bench_begin();
2903   return retval;
2904 }
2905
2906
2907 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
2908   int retval = 0;
2909   smpi_bench_end();
2910   if (win == MPI_WIN_NULL) {
2911     retval = MPI_ERR_WIN;
2912   } else if (group==MPI_GROUP_NULL){
2913     retval = MPI_ERR_GROUP;
2914   }
2915   else {
2916     int rank = smpi_process_index();
2917     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2918     retval = smpi_mpi_win_post(group,assert,win);
2919     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2920   }
2921   smpi_bench_begin();
2922   return retval;
2923 }
2924
2925 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
2926   int retval = 0;
2927   smpi_bench_end();
2928   if (win == MPI_WIN_NULL) {
2929     retval = MPI_ERR_WIN;
2930   } else if (group==MPI_GROUP_NULL){
2931     retval = MPI_ERR_GROUP;
2932   }
2933   else {
2934     int rank = smpi_process_index();
2935     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2936     retval = smpi_mpi_win_start(group,assert,win);
2937     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2938   }
2939   smpi_bench_begin();
2940   return retval;
2941 }
2942
2943
2944 int PMPI_Win_complete(MPI_Win win){
2945   int retval = 0;
2946   smpi_bench_end();
2947   if (win == MPI_WIN_NULL) {
2948     retval = MPI_ERR_WIN;
2949   }
2950   else {
2951     int rank = smpi_process_index();
2952     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2953
2954     retval = smpi_mpi_win_complete(win);
2955
2956     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2957   }
2958   smpi_bench_begin();
2959   return retval;
2960 }
2961
2962 int PMPI_Win_wait(MPI_Win win){
2963   int retval = 0;
2964   smpi_bench_end();
2965   if (win == MPI_WIN_NULL) {
2966     retval = MPI_ERR_WIN;
2967   }
2968   else {
2969     int rank = smpi_process_index();
2970     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, NULL);
2971
2972     retval = smpi_mpi_win_wait(win);
2973
2974     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
2975   }
2976   smpi_bench_begin();
2977   return retval;
2978 }
2979
2980 int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
2981   void *ptr = xbt_malloc(size);
2982   if(!ptr)
2983     return MPI_ERR_NO_MEM;
2984   else {
2985     *(void **)baseptr = ptr;
2986     return MPI_SUCCESS;
2987   }
2988 }
2989
2990 int PMPI_Free_mem(void *baseptr){
2991   xbt_free(baseptr);
2992   return MPI_SUCCESS;
2993 }
2994
2995 int PMPI_Type_set_name(MPI_Datatype  datatype, char * name)
2996 {
2997   int retval = 0;
2998   if (datatype == MPI_DATATYPE_NULL)  {
2999     retval = MPI_ERR_TYPE;
3000   } else if (name == NULL)  {
3001     retval = MPI_ERR_ARG;
3002   } else {
3003     smpi_datatype_set_name(datatype, name);
3004     retval = MPI_SUCCESS;
3005   }
3006   return retval;
3007 }
3008
3009 int PMPI_Type_get_name(MPI_Datatype  datatype, char * name, int* len)
3010 {
3011   int retval = 0;
3012
3013   if (datatype == MPI_DATATYPE_NULL)  {
3014     retval = MPI_ERR_TYPE;
3015   } else if (name == NULL)  {
3016     retval = MPI_ERR_ARG;
3017   } else {
3018     smpi_datatype_get_name(datatype, name, len);
3019     retval = MPI_SUCCESS;
3020   }
3021   return retval;
3022 }
3023
3024
3025 MPI_Datatype PMPI_Type_f2c(MPI_Fint datatype){
3026   return smpi_type_f2c(datatype);
3027 }
3028
3029 MPI_Fint PMPI_Type_c2f(MPI_Datatype datatype){
3030   return smpi_type_c2f( datatype);
3031 }
3032
3033 MPI_Group PMPI_Group_f2c(MPI_Fint group){
3034   return smpi_group_f2c( group);
3035 }
3036
3037 MPI_Fint PMPI_Group_c2f(MPI_Group group){
3038   return smpi_group_c2f(group);
3039 }
3040
3041 MPI_Request PMPI_Request_f2c(MPI_Fint request){
3042   return smpi_request_f2c(request);
3043 }
3044
3045 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
3046   return smpi_request_c2f(request);
3047 }
3048
3049 MPI_Win PMPI_Win_f2c(MPI_Fint win){
3050   return smpi_win_f2c(win);
3051 }
3052
3053 MPI_Fint PMPI_Win_c2f(MPI_Win win){
3054   return smpi_win_c2f(win);
3055 }
3056
3057 MPI_Op PMPI_Op_f2c(MPI_Fint op){
3058   return smpi_op_f2c(op);
3059 }
3060
3061 MPI_Fint PMPI_Op_c2f(MPI_Op op){
3062   return smpi_op_c2f(op);
3063 }
3064
3065 MPI_Comm PMPI_Comm_f2c(MPI_Fint comm){
3066   return smpi_comm_f2c(comm);
3067 }
3068
3069 MPI_Fint PMPI_Comm_c2f(MPI_Comm comm){
3070   return smpi_comm_c2f(comm);
3071 }
3072
3073 MPI_Info PMPI_Info_f2c(MPI_Fint info){
3074   return smpi_info_f2c(info);
3075 }
3076
3077 MPI_Fint PMPI_Info_c2f(MPI_Info info){
3078   return smpi_info_c2f(info);
3079 }
3080
3081 int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
3082   return smpi_comm_keyval_create(copy_fn, delete_fn, keyval, extra_state);
3083 }
3084
3085 int PMPI_Keyval_free(int* keyval) {
3086   return smpi_comm_keyval_free(keyval);
3087 }
3088
3089 int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
3090   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO
3091        ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3092        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3093     return MPI_ERR_ARG;
3094   else if (comm==MPI_COMM_NULL)
3095     return MPI_ERR_COMM;
3096   else
3097     return smpi_comm_attr_delete(comm, keyval);
3098 }
3099
3100 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
3101   static int one = 1;
3102   static int zero = 0;
3103   static int tag_ub = 1000000;
3104   static int last_used_code = MPI_ERR_LASTCODE;
3105
3106   if (comm==MPI_COMM_NULL){
3107     *flag = 0;
3108     return MPI_ERR_COMM;
3109   }
3110
3111   switch (keyval) {
3112   case MPI_HOST:
3113   case MPI_IO:
3114   case MPI_APPNUM:
3115     *flag = 1;
3116     *(int**)attr_value = &zero;
3117     return MPI_SUCCESS;
3118
3119   case MPI_UNIVERSE_SIZE:
3120     *flag = 1;
3121     *(int**)attr_value = &smpi_universe_size;
3122     return MPI_SUCCESS;
3123
3124   case MPI_LASTUSEDCODE:
3125     *flag = 1;
3126     *(int**)attr_value = &last_used_code;
3127     return MPI_SUCCESS;
3128
3129   case MPI_TAG_UB:
3130     *flag=1;
3131     *(int**)attr_value = &tag_ub;
3132     return MPI_SUCCESS;
3133
3134   case MPI_WTIME_IS_GLOBAL:
3135     *flag = 1;
3136     *(int**)attr_value = &one;
3137     return MPI_SUCCESS;
3138
3139   default:
3140     return smpi_comm_attr_get(comm, keyval, attr_value, flag);
3141   }
3142 }
3143
3144 int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
3145   if(keyval == MPI_TAG_UB||keyval == MPI_HOST||keyval == MPI_IO
3146        ||keyval == MPI_WTIME_IS_GLOBAL||keyval == MPI_APPNUM
3147        ||keyval == MPI_UNIVERSE_SIZE||keyval == MPI_LASTUSEDCODE)
3148     return MPI_ERR_ARG;
3149   else if (comm==MPI_COMM_NULL)
3150     return MPI_ERR_COMM;
3151   else
3152   return smpi_comm_attr_put(comm, keyval, attr_value);
3153 }
3154
3155 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
3156 {
3157   return PMPI_Attr_get(comm, comm_keyval, attribute_val,flag);
3158 }
3159
3160 int PMPI_Comm_set_attr (MPI_Comm comm, int comm_keyval, void *attribute_val)
3161 {
3162   return PMPI_Attr_put(comm, comm_keyval, attribute_val);
3163 }
3164
3165 int PMPI_Comm_delete_attr (MPI_Comm comm, int comm_keyval)
3166 {
3167   return PMPI_Attr_delete(comm, comm_keyval);
3168 }
3169
3170 int PMPI_Comm_create_keyval(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn, int* keyval, void* extra_state)
3171 {
3172   return PMPI_Keyval_create(copy_fn, delete_fn, keyval, extra_state);
3173 }
3174
3175 int PMPI_Comm_free_keyval(int* keyval) {
3176   return PMPI_Keyval_free(keyval);
3177 }
3178
3179
3180 int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag)
3181 {
3182   if (type==MPI_DATATYPE_NULL)
3183     return MPI_ERR_TYPE;
3184   else
3185     return smpi_type_attr_get(type, type_keyval, attribute_val, flag);
3186 }
3187
3188 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
3189 {
3190   if (type==MPI_DATATYPE_NULL)
3191     return MPI_ERR_TYPE;
3192   else
3193     return smpi_type_attr_put(type, type_keyval, attribute_val);
3194 }
3195
3196 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
3197 {
3198   if (type==MPI_DATATYPE_NULL)
3199     return MPI_ERR_TYPE;
3200   else
3201     return smpi_type_attr_delete(type, type_keyval);
3202 }
3203
3204 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state)
3205 {
3206   return smpi_type_keyval_create(copy_fn, delete_fn, keyval, extra_state);
3207 }
3208
3209 int PMPI_Type_free_keyval(int* keyval) {
3210   return smpi_type_keyval_free(keyval);
3211 }
3212
3213 int PMPI_Info_create( MPI_Info *info){
3214   if (info == NULL)
3215     return MPI_ERR_ARG;
3216   *info = xbt_new(s_smpi_mpi_info_t, 1);
3217   (*info)->info_dict= xbt_dict_new_homogeneous(NULL);
3218   (*info)->refcount=1;
3219   return MPI_SUCCESS;
3220 }
3221
3222 int PMPI_Info_set( MPI_Info info, char *key, char *value){
3223   if (info == NULL || key == NULL || value == NULL)
3224     return MPI_ERR_ARG;
3225
3226   xbt_dict_set(info->info_dict, key, (void*)value, NULL);
3227   return MPI_SUCCESS;
3228 }
3229
3230 int PMPI_Info_free( MPI_Info *info){
3231   if (info == NULL || *info==NULL)
3232     return MPI_ERR_ARG;
3233   (*info)->refcount--;
3234   if((*info)->refcount==0){
3235     xbt_dict_free(&((*info)->info_dict));
3236     xbt_free(*info);
3237   }
3238   *info=MPI_INFO_NULL;
3239   return MPI_SUCCESS;
3240 }
3241
3242 int PMPI_Info_get(MPI_Info info,char *key,int valuelen, char *value, int *flag){
3243   if (info == NULL || key == NULL || valuelen <0)
3244     return MPI_ERR_ARG;
3245   if (value == NULL)
3246     return MPI_ERR_INFO_VALUE;
3247   *flag=FALSE;
3248   char* tmpvalue=(char*)xbt_dict_get_or_null(info->info_dict, key);
3249   if(tmpvalue){
3250     memcpy(value,tmpvalue, (strlen(tmpvalue) + 1 < valuelen) ?
3251                          strlen(tmpvalue) + 1 : valuelen);
3252     *flag=TRUE;
3253   }
3254   return MPI_SUCCESS;
3255 }
3256
3257 int PMPI_Info_dup(MPI_Info info, MPI_Info *newinfo){
3258   if (info == NULL || newinfo==NULL)
3259     return MPI_ERR_ARG;
3260   *newinfo = xbt_new(s_smpi_mpi_info_t, 1);
3261   (*newinfo)->info_dict= xbt_dict_new_homogeneous(NULL);
3262   xbt_dict_cursor_t cursor = NULL;
3263   int *key;
3264   void* data;
3265   xbt_dict_foreach(info->info_dict,cursor,key,data){
3266     xbt_dict_set((*newinfo)->info_dict, (char*)key, data, NULL);
3267   }
3268   return MPI_SUCCESS;
3269 }
3270
3271 int PMPI_Info_delete(MPI_Info info, char *key){
3272   xbt_ex_t e;
3273   if (info == NULL || key==NULL)
3274     return MPI_ERR_ARG;
3275   TRY {
3276   xbt_dict_remove(info->info_dict, key);
3277   }CATCH(e){
3278     xbt_ex_free(e);
3279     return MPI_ERR_INFO_NOKEY;
3280   }
3281   return MPI_SUCCESS;
3282 }
3283
3284 int PMPI_Info_get_nkeys( MPI_Info info, int *nkeys){
3285   if (info == NULL || nkeys==NULL)
3286     return MPI_ERR_ARG;
3287   *nkeys=xbt_dict_size(info->info_dict);
3288   return MPI_SUCCESS;
3289 }
3290
3291 int PMPI_Info_get_nthkey( MPI_Info info, int n, char *key){
3292   if (info == NULL || key==NULL || n<0 || n> MPI_MAX_INFO_KEY)
3293     return MPI_ERR_ARG;
3294
3295   xbt_dict_cursor_t cursor = NULL;
3296   char *keyn;
3297   void* data;
3298   int num=0;
3299   xbt_dict_foreach(info->info_dict,cursor,keyn,data){
3300     if(num==n){
3301      strcpy(key,keyn);
3302       return MPI_SUCCESS;
3303     }
3304     num++;
3305   }
3306   return MPI_ERR_ARG;
3307 }
3308
3309 int PMPI_Info_get_valuelen( MPI_Info info, char *key, int *valuelen, int *flag){
3310   if (info == NULL || key == NULL || valuelen <0)
3311     return MPI_ERR_ARG;
3312   *flag=FALSE;
3313   char* tmpvalue=(char*)xbt_dict_get_or_null(info->info_dict, key);
3314   if(tmpvalue){
3315     *valuelen=strlen(tmpvalue);
3316     *flag=TRUE;
3317   }
3318   return MPI_SUCCESS;
3319 }
3320
3321 int PMPI_Unpack(void* inbuf, int incount, int* position, void* outbuf, int outcount, MPI_Datatype type, MPI_Comm comm) {
3322   if(incount<0 || outcount < 0 || inbuf==NULL || outbuf==NULL)
3323     return MPI_ERR_ARG;
3324   if(!is_datatype_valid(type))
3325     return MPI_ERR_TYPE;
3326   if(comm==MPI_COMM_NULL)
3327     return MPI_ERR_COMM;
3328   return smpi_mpi_unpack(inbuf, incount, position, outbuf,outcount,type, comm);
3329 }
3330
3331 int PMPI_Pack(void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount, int* position, MPI_Comm comm) {
3332   if(incount<0 || outcount < 0|| inbuf==NULL || outbuf==NULL)
3333     return MPI_ERR_ARG;
3334   if(!is_datatype_valid(type))
3335     return MPI_ERR_TYPE;
3336   if(comm==MPI_COMM_NULL)
3337     return MPI_ERR_COMM;
3338   return smpi_mpi_pack(inbuf, incount, type, outbuf,outcount,position, comm);
3339 }
3340
3341 int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
3342   if(incount<0)
3343     return MPI_ERR_ARG;
3344   if(!is_datatype_valid(datatype))
3345     return MPI_ERR_TYPE;
3346   if(comm==MPI_COMM_NULL)
3347     return MPI_ERR_COMM;
3348
3349   *size=incount*smpi_datatype_size(datatype);
3350
3351   return MPI_SUCCESS;
3352 }
3353
3354
3355 /* The following calls are not yet implemented and will fail at runtime. */
3356 /* Once implemented, please move them above this notice. */
3357
3358 #define NOT_YET_IMPLEMENTED {                                           \
3359     XBT_WARN("Not yet implemented : %s. Please contact the Simgrid team if support is needed", __FUNCTION__); \
3360     return MPI_SUCCESS;                                                 \
3361   }
3362
3363 MPI_Errhandler PMPI_Errhandler_f2c(MPI_Fint errhandler){
3364   NOT_YET_IMPLEMENTED
3365 }
3366
3367 MPI_Fint PMPI_Errhandler_c2f(MPI_Errhandler errhandler){
3368   NOT_YET_IMPLEMENTED
3369 }
3370
3371 int PMPI_Cart_map(MPI_Comm comm_old, int ndims, int* dims, int* periods, int* newrank) {
3372   NOT_YET_IMPLEMENTED
3373 }
3374
3375 int PMPI_Graph_create(MPI_Comm comm_old, int nnodes, int* index, int* edges, int reorder, MPI_Comm* comm_graph) {
3376   NOT_YET_IMPLEMENTED
3377 }
3378
3379 int PMPI_Graph_get(MPI_Comm comm, int maxindex, int maxedges, int* index, int* edges) {
3380   NOT_YET_IMPLEMENTED
3381 }
3382
3383 int PMPI_Graph_map(MPI_Comm comm_old, int nnodes, int* index, int* edges, int* newrank) {
3384   NOT_YET_IMPLEMENTED
3385 }
3386
3387 int PMPI_Graph_neighbors(MPI_Comm comm, int rank, int maxneighbors, int* neighbors) {
3388   NOT_YET_IMPLEMENTED
3389 }
3390
3391 int PMPI_Graph_neighbors_count(MPI_Comm comm, int rank, int* nneighbors) {
3392   NOT_YET_IMPLEMENTED
3393 }
3394
3395 int PMPI_Graphdims_get(MPI_Comm comm, int* nnodes, int* nedges) {
3396   NOT_YET_IMPLEMENTED
3397 }
3398
3399 int PMPI_Topo_test(MPI_Comm comm, int* top_type) {
3400   NOT_YET_IMPLEMENTED
3401 }
3402
3403 int PMPI_Errhandler_create(MPI_Handler_function* function, MPI_Errhandler* errhandler) {
3404   NOT_YET_IMPLEMENTED
3405 }
3406
3407 int PMPI_Errhandler_free(MPI_Errhandler* errhandler) {
3408   NOT_YET_IMPLEMENTED
3409 }
3410
3411 int PMPI_Errhandler_get(MPI_Comm comm, MPI_Errhandler* errhandler) {
3412   NOT_YET_IMPLEMENTED
3413 }
3414
3415 int PMPI_Error_string(int errorcode, char* string, int* resultlen) {
3416   NOT_YET_IMPLEMENTED
3417 }
3418
3419 int PMPI_Errhandler_set(MPI_Comm comm, MPI_Errhandler errhandler) {
3420   NOT_YET_IMPLEMENTED
3421 }
3422
3423 int PMPI_Comm_set_errhandler(MPI_Comm comm, MPI_Errhandler errhandler) {
3424   NOT_YET_IMPLEMENTED
3425 }
3426
3427 int PMPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler) {
3428   NOT_YET_IMPLEMENTED
3429 }
3430
3431 int PMPI_Comm_get_errhandler(MPI_Comm comm, MPI_Errhandler* errhandler) {
3432   NOT_YET_IMPLEMENTED
3433 }
3434
3435 int PMPI_Cancel(MPI_Request* request) {
3436   NOT_YET_IMPLEMENTED
3437 }
3438
3439 int PMPI_Buffer_attach(void* buffer, int size) {
3440   NOT_YET_IMPLEMENTED
3441 }
3442
3443 int PMPI_Buffer_detach(void* buffer, int* size) {
3444   NOT_YET_IMPLEMENTED
3445 }
3446
3447 int PMPI_Comm_test_inter(MPI_Comm comm, int* flag) {
3448   NOT_YET_IMPLEMENTED
3449 }
3450
3451 int PMPI_Pcontrol(const int level )
3452 {
3453   NOT_YET_IMPLEMENTED
3454 }
3455
3456
3457 int PMPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out) {
3458   NOT_YET_IMPLEMENTED
3459 }
3460
3461 int PMPI_Intercomm_merge(MPI_Comm comm, int high, MPI_Comm* comm_out) {
3462   NOT_YET_IMPLEMENTED
3463 }
3464
3465 int PMPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
3466   NOT_YET_IMPLEMENTED
3467 }
3468
3469 int PMPI_Bsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3470   NOT_YET_IMPLEMENTED
3471 }
3472
3473 int PMPI_Ibsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3474   NOT_YET_IMPLEMENTED
3475 }
3476
3477 int PMPI_Comm_remote_group(MPI_Comm comm, MPI_Group* group) {
3478   NOT_YET_IMPLEMENTED
3479 }
3480
3481 int PMPI_Comm_remote_size(MPI_Comm comm, int* size) {
3482   NOT_YET_IMPLEMENTED
3483 }
3484
3485 int PMPI_Rsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) {
3486   NOT_YET_IMPLEMENTED
3487 }
3488
3489 int PMPI_Rsend_init(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3490   NOT_YET_IMPLEMENTED
3491 }
3492
3493 int PMPI_Irsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) {
3494   NOT_YET_IMPLEMENTED
3495 }
3496
3497 int PMPI_Test_cancelled(MPI_Status* status, int* flag) {
3498   NOT_YET_IMPLEMENTED
3499 }
3500
3501
3502
3503 int PMPI_Pack_external_size(char *datarep, int incount, MPI_Datatype datatype, MPI_Aint *size){
3504   NOT_YET_IMPLEMENTED
3505 }
3506
3507 int PMPI_Pack_external(char *datarep, void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, MPI_Aint outcount, MPI_Aint *position){
3508   NOT_YET_IMPLEMENTED
3509 }
3510
3511 int PMPI_Unpack_external( char *datarep, void *inbuf, MPI_Aint insize, MPI_Aint *position, void *outbuf, int outcount, MPI_Datatype datatype){
3512   NOT_YET_IMPLEMENTED
3513 }
3514
3515 int PMPI_Get_elements(MPI_Status* status, MPI_Datatype datatype, int* elements) {
3516   NOT_YET_IMPLEMENTED
3517 }
3518
3519
3520
3521 int PMPI_Type_get_envelope( MPI_Datatype datatype, int *num_integers,
3522                             int *num_addresses, int *num_datatypes, int *combiner){
3523   NOT_YET_IMPLEMENTED
3524 }
3525
3526 int PMPI_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses,
3527                            int max_datatypes, int* array_of_integers, MPI_Aint* array_of_addresses,
3528                            MPI_Datatype* array_of_datatypes){
3529   NOT_YET_IMPLEMENTED
3530 }
3531
3532 int PMPI_Type_create_darray(int size, int rank, int ndims, int* array_of_gsizes,
3533                             int* array_of_distribs, int* array_of_dargs, int* array_of_psizes,
3534                             int order, MPI_Datatype oldtype, MPI_Datatype *newtype) {
3535   NOT_YET_IMPLEMENTED
3536 }
3537
3538 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){
3539   NOT_YET_IMPLEMENTED
3540 }
3541
3542 int PMPI_Type_match_size(int typeclass,int size,MPI_Datatype *datatype){
3543   NOT_YET_IMPLEMENTED
3544 }
3545
3546 int PMPI_Alltoallw( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes,
3547                     void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes,
3548                     MPI_Comm comm){
3549   NOT_YET_IMPLEMENTED
3550 }
3551
3552 int PMPI_Comm_set_name(MPI_Comm comm, char* name){
3553   NOT_YET_IMPLEMENTED
3554 }
3555
3556 int PMPI_Comm_dup_with_info(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm){
3557   NOT_YET_IMPLEMENTED
3558 }
3559
3560 int PMPI_Comm_split_type(MPI_Comm comm, int split_type, int key, MPI_Info info, MPI_Comm *newcomm){
3561   NOT_YET_IMPLEMENTED
3562 }
3563
3564 int PMPI_Comm_set_info (MPI_Comm comm, MPI_Info info){
3565   NOT_YET_IMPLEMENTED
3566 }
3567
3568 int PMPI_Comm_get_info (MPI_Comm comm, MPI_Info* info){
3569   NOT_YET_IMPLEMENTED
3570 }
3571
3572 int PMPI_Comm_create_errhandler( MPI_Comm_errhandler_fn *function, MPI_Errhandler *errhandler){
3573   NOT_YET_IMPLEMENTED
3574 }
3575
3576 int PMPI_Add_error_class( int *errorclass){
3577   NOT_YET_IMPLEMENTED
3578 }
3579
3580 int PMPI_Add_error_code(  int errorclass, int *errorcode){
3581   NOT_YET_IMPLEMENTED
3582 }
3583
3584 int PMPI_Add_error_string( int errorcode, char *string){
3585   NOT_YET_IMPLEMENTED
3586 }
3587
3588 int PMPI_Comm_call_errhandler(MPI_Comm comm,int errorcode){
3589   NOT_YET_IMPLEMENTED
3590 }
3591
3592 int PMPI_Request_get_status( MPI_Request request, int *flag, MPI_Status *status){
3593   NOT_YET_IMPLEMENTED
3594 }
3595
3596 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){
3597   NOT_YET_IMPLEMENTED
3598 }
3599
3600 int PMPI_Grequest_complete( MPI_Request request){
3601   NOT_YET_IMPLEMENTED
3602 }
3603
3604 int PMPI_Status_set_cancelled(MPI_Status *status,int flag){
3605   NOT_YET_IMPLEMENTED
3606 }
3607
3608 int PMPI_Status_set_elements( MPI_Status *status, MPI_Datatype datatype, int count){
3609   NOT_YET_IMPLEMENTED
3610 }
3611
3612 int PMPI_Comm_connect( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3613   NOT_YET_IMPLEMENTED
3614 }
3615
3616 int PMPI_Publish_name( char *service_name, MPI_Info info, char *port_name){
3617   NOT_YET_IMPLEMENTED
3618 }
3619
3620 int PMPI_Unpublish_name( char *service_name, MPI_Info info, char *port_name){
3621   NOT_YET_IMPLEMENTED
3622 }
3623
3624 int PMPI_Lookup_name( char *service_name, MPI_Info info, char *port_name){
3625   NOT_YET_IMPLEMENTED
3626 }
3627
3628 int PMPI_Comm_join( int fd, MPI_Comm *intercomm){
3629   NOT_YET_IMPLEMENTED
3630 }
3631
3632 int PMPI_Open_port( MPI_Info info, char *port_name){
3633   NOT_YET_IMPLEMENTED
3634 }
3635
3636 int PMPI_Close_port(char *port_name){
3637   NOT_YET_IMPLEMENTED
3638 }
3639
3640 int PMPI_Comm_accept( char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm){
3641   NOT_YET_IMPLEMENTED
3642 }
3643
3644 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){
3645   NOT_YET_IMPLEMENTED
3646 }
3647
3648 int PMPI_Comm_spawn_multiple( int count, char **array_of_commands, char*** array_of_argv,
3649                               int* array_of_maxprocs, MPI_Info* array_of_info, int root,
3650                               MPI_Comm comm, MPI_Comm *intercomm, int* array_of_errcodes){
3651   NOT_YET_IMPLEMENTED
3652 }
3653
3654 int PMPI_Comm_get_parent( MPI_Comm *parent){
3655   NOT_YET_IMPLEMENTED
3656 }
3657
3658 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win) {
3659   NOT_YET_IMPLEMENTED
3660 }
3661
3662 int PMPI_Win_test(MPI_Win win, int *flag){
3663   NOT_YET_IMPLEMENTED
3664 }
3665
3666 int PMPI_Win_unlock(int rank, MPI_Win win){
3667   NOT_YET_IMPLEMENTED
3668 }