Logo AND Algorithmique Numérique Distribuée

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