Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
a bit of unperfect simplification in this SMPI+TI TRacing mess
[simgrid.git] / src / smpi / bindings / smpi_pmpi_request.cpp
1 /* Copyright (c) 2007-2017. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "private.hpp"
7 #include "smpi_comm.hpp"
8 #include "smpi_datatype.hpp"
9 #include "smpi_process.hpp"
10 #include "smpi_request.hpp"
11
12 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
13
14 /* PMPI User level calls */
15 extern "C" { // Obviously, the C MPI interface should use the C linkage
16
17 int PMPI_Send_init(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
18 {
19   int retval = 0;
20
21   smpi_bench_end();
22   if (request == nullptr) {
23     retval = MPI_ERR_ARG;
24   } else if (comm == MPI_COMM_NULL) {
25     retval = MPI_ERR_COMM;
26   } else if (not datatype->is_valid()) {
27     retval = MPI_ERR_TYPE;
28   } else if (dst == MPI_PROC_NULL) {
29     retval = MPI_SUCCESS;
30   } else {
31     *request = simgrid::smpi::Request::send_init(buf, count, datatype, dst, tag, comm);
32     retval   = MPI_SUCCESS;
33   }
34   smpi_bench_begin();
35   if (retval != MPI_SUCCESS && request != nullptr)
36     *request = MPI_REQUEST_NULL;
37   return retval;
38 }
39
40 int PMPI_Recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
41 {
42   int retval = 0;
43
44   smpi_bench_end();
45   if (request == nullptr) {
46     retval = MPI_ERR_ARG;
47   } else if (comm == MPI_COMM_NULL) {
48     retval = MPI_ERR_COMM;
49   } else if (not datatype->is_valid()) {
50     retval = MPI_ERR_TYPE;
51   } else if (src == MPI_PROC_NULL) {
52     retval = MPI_SUCCESS;
53   } else {
54     *request = simgrid::smpi::Request::recv_init(buf, count, datatype, src, tag, comm);
55     retval = MPI_SUCCESS;
56   }
57   smpi_bench_begin();
58   if (retval != MPI_SUCCESS && request != nullptr)
59     *request = MPI_REQUEST_NULL;
60   return retval;
61 }
62
63 int PMPI_Ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
64 {
65   int retval = 0;
66
67   smpi_bench_end();
68   if (request == nullptr) {
69     retval = MPI_ERR_ARG;
70   } else if (comm == MPI_COMM_NULL) {
71     retval = MPI_ERR_COMM;
72   } else if (not datatype->is_valid()) {
73     retval = MPI_ERR_TYPE;
74   } else if (dst == MPI_PROC_NULL) {
75     retval = MPI_SUCCESS;
76   } else {
77     *request = simgrid::smpi::Request::ssend_init(buf, count, datatype, dst, tag, comm);
78     retval = MPI_SUCCESS;
79   }
80   smpi_bench_begin();
81   if (retval != MPI_SUCCESS && request != nullptr)
82     *request = MPI_REQUEST_NULL;
83   return retval;
84 }
85
86 int PMPI_Start(MPI_Request * request)
87 {
88   int retval = 0;
89
90   smpi_bench_end();
91   if (request == nullptr || *request == MPI_REQUEST_NULL) {
92     retval = MPI_ERR_REQUEST;
93   } else {
94     (*request)->start();
95     retval = MPI_SUCCESS;
96   }
97   smpi_bench_begin();
98   return retval;
99 }
100
101 int PMPI_Startall(int count, MPI_Request * requests)
102 {
103   int retval;
104   smpi_bench_end();
105   if (requests == nullptr) {
106     retval = MPI_ERR_ARG;
107   } else {
108     retval = MPI_SUCCESS;
109     for (int i = 0; i < count; i++) {
110       if(requests[i] == MPI_REQUEST_NULL) {
111         retval = MPI_ERR_REQUEST;
112       }
113     }
114     if(retval != MPI_ERR_REQUEST) {
115       simgrid::smpi::Request::startall(count, requests);
116     }
117   }
118   smpi_bench_begin();
119   return retval;
120 }
121
122 int PMPI_Request_free(MPI_Request * request)
123 {
124   int retval = 0;
125
126   smpi_bench_end();
127   if (*request == MPI_REQUEST_NULL) {
128     retval = MPI_ERR_ARG;
129   } else {
130     simgrid::smpi::Request::unref(request);
131     retval = MPI_SUCCESS;
132   }
133   smpi_bench_begin();
134   return retval;
135 }
136
137 int PMPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request)
138 {
139   int retval = 0;
140
141   smpi_bench_end();
142
143   if (request == nullptr) {
144     retval = MPI_ERR_ARG;
145   } else if (comm == MPI_COMM_NULL) {
146     retval = MPI_ERR_COMM;
147   } else if (src == MPI_PROC_NULL) {
148     *request = MPI_REQUEST_NULL;
149     retval = MPI_SUCCESS;
150   } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
151     retval = MPI_ERR_RANK;
152   } else if ((count < 0) || (buf==nullptr && count > 0)) {
153     retval = MPI_ERR_COUNT;
154   } else if (not datatype->is_valid()) {
155     retval = MPI_ERR_TYPE;
156   } else if(tag<0 && tag !=  MPI_ANY_TAG){
157     retval = MPI_ERR_TAG;
158   } else {
159
160     int rank       = smpi_process()->index();
161     int src_traced = comm->group()->index(src);
162
163     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
164     extra->type = TRACING_IRECV;
165     extra->src = src_traced;
166     extra->dst = rank;
167     extra->datatype1       = encode_datatype(datatype);
168     extra->send_size       = datatype->is_basic() ? count : count * datatype->size();
169     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
170
171     *request = simgrid::smpi::Request::irecv(buf, count, datatype, src, tag, comm);
172     retval = MPI_SUCCESS;
173
174     TRACE_smpi_ptp_out(rank);
175   }
176
177   smpi_bench_begin();
178   if (retval != MPI_SUCCESS && request != nullptr)
179     *request = MPI_REQUEST_NULL;
180   return retval;
181 }
182
183
184 int PMPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request)
185 {
186   int retval = 0;
187
188   smpi_bench_end();
189   if (request == nullptr) {
190     retval = MPI_ERR_ARG;
191   } else if (comm == MPI_COMM_NULL) {
192     retval = MPI_ERR_COMM;
193   } else if (dst == MPI_PROC_NULL) {
194     *request = MPI_REQUEST_NULL;
195     retval = MPI_SUCCESS;
196   } else if (dst >= comm->group()->size() || dst <0){
197     retval = MPI_ERR_RANK;
198   } else if ((count < 0) || (buf==nullptr && count > 0)) {
199     retval = MPI_ERR_COUNT;
200   } else if (not datatype->is_valid()) {
201     retval = MPI_ERR_TYPE;
202   } else if(tag<0 && tag !=  MPI_ANY_TAG){
203     retval = MPI_ERR_TAG;
204   } else {
205     int rank               = smpi_process()->index();
206     int dst_traced = comm->group()->index(dst);
207     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
208     extra->type = TRACING_ISEND;
209     extra->src = rank;
210     extra->dst = dst_traced;
211     extra->datatype1       = encode_datatype(datatype);
212     extra->send_size       = datatype->is_basic() ? count : count * datatype->size();
213     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
214     TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
215
216     *request = simgrid::smpi::Request::isend(buf, count, datatype, dst, tag, comm);
217     retval = MPI_SUCCESS;
218
219     TRACE_smpi_ptp_out(rank);
220   }
221
222   smpi_bench_begin();
223   if (retval != MPI_SUCCESS && request!=nullptr)
224     *request = MPI_REQUEST_NULL;
225   return retval;
226 }
227
228 int PMPI_Issend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
229 {
230   int retval = 0;
231
232   smpi_bench_end();
233   if (request == nullptr) {
234     retval = MPI_ERR_ARG;
235   } else if (comm == MPI_COMM_NULL) {
236     retval = MPI_ERR_COMM;
237   } else if (dst == MPI_PROC_NULL) {
238     *request = MPI_REQUEST_NULL;
239     retval = MPI_SUCCESS;
240   } else if (dst >= comm->group()->size() || dst <0){
241     retval = MPI_ERR_RANK;
242   } else if ((count < 0)|| (buf==nullptr && count > 0)) {
243     retval = MPI_ERR_COUNT;
244   } else if (not datatype->is_valid()) {
245     retval = MPI_ERR_TYPE;
246   } else if(tag<0 && tag !=  MPI_ANY_TAG){
247     retval = MPI_ERR_TAG;
248   } else {
249     int rank               = smpi_process()->index();
250     int dst_traced = comm->group()->index(dst);
251     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
252     extra->type = TRACING_ISSEND;
253     extra->src = rank;
254     extra->dst = dst_traced;
255     extra->datatype1       = encode_datatype(datatype);
256     extra->send_size       = datatype->is_basic() ? count : count * datatype->size();
257     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
258     TRACE_smpi_send(rank, rank, dst_traced, tag, count*datatype->size());
259
260     *request = simgrid::smpi::Request::issend(buf, count, datatype, dst, tag, comm);
261     retval = MPI_SUCCESS;
262
263     TRACE_smpi_ptp_out(rank);
264   }
265
266   smpi_bench_begin();
267   if (retval != MPI_SUCCESS && request!=nullptr)
268     *request = MPI_REQUEST_NULL;
269   return retval;
270 }
271
272 int PMPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
273 {
274   int retval = 0;
275
276   smpi_bench_end();
277   if (comm == MPI_COMM_NULL) {
278     retval = MPI_ERR_COMM;
279   } else if (src == MPI_PROC_NULL) {
280     simgrid::smpi::Status::empty(status);
281     status->MPI_SOURCE = MPI_PROC_NULL;
282     retval = MPI_SUCCESS;
283   } else if (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0)){
284     retval = MPI_ERR_RANK;
285   } else if ((count < 0) || (buf==nullptr && count > 0)) {
286     retval = MPI_ERR_COUNT;
287   } else if (not datatype->is_valid()) {
288     retval = MPI_ERR_TYPE;
289   } else if(tag<0 && tag !=  MPI_ANY_TAG){
290     retval = MPI_ERR_TAG;
291   } else {
292     int rank               = smpi_process()->index();
293     int src_traced         = comm->group()->index(src);
294     instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
295     extra->type            = TRACING_RECV;
296     extra->src             = src_traced;
297     extra->dst             = rank;
298     extra->datatype1       = encode_datatype(datatype);
299     extra->send_size       = datatype->is_basic() ? count : count * datatype->size();
300     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
301
302     simgrid::smpi::Request::recv(buf, count, datatype, src, tag, comm, status);
303     retval = MPI_SUCCESS;
304
305     // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
306     if (status != MPI_STATUS_IGNORE) {
307       src_traced = comm->group()->index(status->MPI_SOURCE);
308       if (not TRACE_smpi_view_internals()) {
309         TRACE_smpi_recv(src_traced, rank, tag);
310       }
311     }
312     TRACE_smpi_ptp_out(rank);
313   }
314
315   smpi_bench_begin();
316   return retval;
317 }
318
319 int PMPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
320 {
321   int retval = 0;
322
323   smpi_bench_end();
324
325   if (comm == MPI_COMM_NULL) {
326     retval = MPI_ERR_COMM;
327   } else if (dst == MPI_PROC_NULL) {
328     retval = MPI_SUCCESS;
329   } else if (dst >= comm->group()->size() || dst <0){
330     retval = MPI_ERR_RANK;
331   } else if ((count < 0) || (buf == nullptr && count > 0)) {
332     retval = MPI_ERR_COUNT;
333   } else if (not datatype->is_valid()) {
334     retval = MPI_ERR_TYPE;
335   } else if(tag < 0 && tag !=  MPI_ANY_TAG){
336     retval = MPI_ERR_TAG;
337   } else {
338     int rank               = smpi_process()->index();
339     int dst_traced         = comm->group()->index(dst);
340     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
341     extra->type            = TRACING_SEND;
342     extra->src             = rank;
343     extra->dst             = dst_traced;
344     extra->datatype1       = encode_datatype(datatype);
345     extra->send_size       = datatype->is_basic() ? count : count * datatype->size();
346     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
347     if (not TRACE_smpi_view_internals()) {
348       TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
349     }
350
351     simgrid::smpi::Request::send(buf, count, datatype, dst, tag, comm);
352     retval = MPI_SUCCESS;
353
354     TRACE_smpi_ptp_out(rank);
355   }
356
357   smpi_bench_begin();
358   return retval;
359 }
360
361 int PMPI_Ssend(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
362   int retval = 0;
363
364   smpi_bench_end();
365
366   if (comm == MPI_COMM_NULL) {
367     retval = MPI_ERR_COMM;
368   } else if (dst == MPI_PROC_NULL) {
369     retval = MPI_SUCCESS;
370   } else if (dst >= comm->group()->size() || dst <0){
371     retval = MPI_ERR_RANK;
372   } else if ((count < 0) || (buf==nullptr && count > 0)) {
373     retval = MPI_ERR_COUNT;
374   } else if (not datatype->is_valid()) {
375     retval = MPI_ERR_TYPE;
376   } else if(tag<0 && tag !=  MPI_ANY_TAG){
377     retval = MPI_ERR_TAG;
378   } else {
379     int rank               = smpi_process()->index();
380     int dst_traced         = comm->group()->index(dst);
381     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
382     extra->type            = TRACING_SSEND;
383     extra->src             = rank;
384     extra->dst             = dst_traced;
385     extra->datatype1       = encode_datatype(datatype);
386     extra->send_size       = datatype->is_basic() ? count : count * datatype->size();
387
388     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
389     TRACE_smpi_send(rank, rank, dst_traced, tag,count*datatype->size());
390
391     simgrid::smpi::Request::ssend(buf, count, datatype, dst, tag, comm);
392     retval = MPI_SUCCESS;
393
394     TRACE_smpi_ptp_out(rank);
395   }
396
397   smpi_bench_begin();
398   return retval;
399 }
400
401 int PMPI_Sendrecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf,
402                   int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status* status)
403 {
404   int retval = 0;
405
406   smpi_bench_end();
407
408   if (comm == MPI_COMM_NULL) {
409     retval = MPI_ERR_COMM;
410   } else if (not sendtype->is_valid() || not recvtype->is_valid()) {
411     retval = MPI_ERR_TYPE;
412   } else if (src == MPI_PROC_NULL || dst == MPI_PROC_NULL) {
413     simgrid::smpi::Status::empty(status);
414     status->MPI_SOURCE = MPI_PROC_NULL;
415     retval             = MPI_SUCCESS;
416   }else if (dst >= comm->group()->size() || dst <0 ||
417       (src!=MPI_ANY_SOURCE && (src >= comm->group()->size() || src <0))){
418     retval = MPI_ERR_RANK;
419   } else if ((sendcount < 0 || recvcount<0) ||
420       (sendbuf==nullptr && sendcount > 0) || (recvbuf==nullptr && recvcount>0)) {
421     retval = MPI_ERR_COUNT;
422   } else if((sendtag<0 && sendtag !=  MPI_ANY_TAG)||(recvtag<0 && recvtag != MPI_ANY_TAG)){
423     retval = MPI_ERR_TAG;
424   } else {
425     int rank               = smpi_process()->index();
426     int dst_traced         = comm->group()->index(dst);
427     int src_traced         = comm->group()->index(src);
428     instr_extra_data extra = xbt_new0(s_instr_extra_data_t, 1);
429     extra->type            = TRACING_SENDRECV;
430     extra->src             = src_traced;
431     extra->dst             = dst_traced;
432     extra->datatype1       = encode_datatype(sendtype);
433     extra->send_size       = sendtype->is_basic() ? sendcount : sendcount * sendtype->size();
434     extra->datatype2       = encode_datatype(recvtype);
435     extra->recv_size       = recvtype->is_basic() ? recvcount : recvcount * recvtype->size();
436
437     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
438     TRACE_smpi_send(rank, rank, dst_traced, sendtag, sendcount * sendtype->size());
439
440     simgrid::smpi::Request::sendrecv(sendbuf, sendcount, sendtype, dst, sendtag, recvbuf, recvcount, recvtype, src,
441                                      recvtag, comm, status);
442     retval = MPI_SUCCESS;
443
444     TRACE_smpi_ptp_out(rank);
445     TRACE_smpi_recv(src_traced, rank, recvtag);
446   }
447
448   smpi_bench_begin();
449   return retval;
450 }
451
452 int PMPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, int sendtag, int src, int recvtag,
453                           MPI_Comm comm, MPI_Status* status)
454 {
455   int retval = 0;
456   if (not datatype->is_valid()) {
457     return MPI_ERR_TYPE;
458   } else if (count < 0) {
459     return MPI_ERR_COUNT;
460   } else {
461     int size = datatype->get_extent() * count;
462     void* recvbuf = xbt_new0(char, size);
463     retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
464     if(retval==MPI_SUCCESS){
465       simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
466     }
467     xbt_free(recvbuf);
468
469   }
470   return retval;
471 }
472
473 int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
474 {
475   int retval = 0;
476   smpi_bench_end();
477   if (request == nullptr || flag == nullptr) {
478     retval = MPI_ERR_ARG;
479   } else if (*request == MPI_REQUEST_NULL) {
480     *flag= true;
481     simgrid::smpi::Status::empty(status);
482     retval = MPI_SUCCESS;
483   } else {
484     int rank = ((*request)->comm() != MPI_COMM_NULL) ? smpi_process()->index() : -1;
485
486     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
487     extra->type = TRACING_TEST;
488     TRACE_smpi_testing_in(rank, extra);
489
490     *flag = simgrid::smpi::Request::test(request,status);
491
492     TRACE_smpi_testing_out(rank);
493     retval = MPI_SUCCESS;
494   }
495   smpi_bench_begin();
496   return retval;
497 }
498
499 int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status)
500 {
501   int retval = 0;
502
503   smpi_bench_end();
504   if (index == nullptr || flag == nullptr) {
505     retval = MPI_ERR_ARG;
506   } else {
507     *flag = simgrid::smpi::Request::testany(count, requests, index, status);
508     retval = MPI_SUCCESS;
509   }
510   smpi_bench_begin();
511   return retval;
512 }
513
514 int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* statuses)
515 {
516   int retval = 0;
517
518   smpi_bench_end();
519   if (flag == nullptr) {
520     retval = MPI_ERR_ARG;
521   } else {
522     *flag = simgrid::smpi::Request::testall(count, requests, statuses);
523     retval = MPI_SUCCESS;
524   }
525   smpi_bench_begin();
526   return retval;
527 }
528
529 int PMPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status* status) {
530   int retval = 0;
531   smpi_bench_end();
532
533   if (status == nullptr) {
534     retval = MPI_ERR_ARG;
535   } else if (comm == MPI_COMM_NULL) {
536     retval = MPI_ERR_COMM;
537   } else if (source == MPI_PROC_NULL) {
538     simgrid::smpi::Status::empty(status);
539     status->MPI_SOURCE = MPI_PROC_NULL;
540     retval = MPI_SUCCESS;
541   } else {
542     simgrid::smpi::Request::probe(source, tag, comm, status);
543     retval = MPI_SUCCESS;
544   }
545   smpi_bench_begin();
546   return retval;
547 }
548
549 int PMPI_Iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) {
550   int retval = 0;
551   smpi_bench_end();
552
553   if (flag == nullptr) {
554     retval = MPI_ERR_ARG;
555   } else if (comm == MPI_COMM_NULL) {
556     retval = MPI_ERR_COMM;
557   } else if (source == MPI_PROC_NULL) {
558     *flag=true;
559     simgrid::smpi::Status::empty(status);
560     status->MPI_SOURCE = MPI_PROC_NULL;
561     retval = MPI_SUCCESS;
562   } else {
563     simgrid::smpi::Request::iprobe(source, tag, comm, flag, status);
564     retval = MPI_SUCCESS;
565   }
566   smpi_bench_begin();
567   return retval;
568 }
569
570 int PMPI_Wait(MPI_Request * request, MPI_Status * status)
571 {
572   int retval = 0;
573
574   smpi_bench_end();
575
576   simgrid::smpi::Status::empty(status);
577
578   if (request == nullptr) {
579     retval = MPI_ERR_ARG;
580   } else if (*request == MPI_REQUEST_NULL) {
581     retval = MPI_SUCCESS;
582   } else {
583     int rank = (*request)->comm() != MPI_COMM_NULL ? smpi_process()->index() : -1;
584
585     int src_traced = (*request)->src();
586     int dst_traced = (*request)->dst();
587     int tag_traced= (*request)->tag();
588     MPI_Comm comm = (*request)->comm();
589     int is_wait_for_receive = ((*request)->flags() & RECV);
590     instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
591     extra->type = TRACING_WAIT;
592     TRACE_smpi_ptp_in(rank, __FUNCTION__, extra);
593
594     simgrid::smpi::Request::wait(request, status);
595     retval = MPI_SUCCESS;
596
597     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
598     TRACE_smpi_ptp_out(rank);
599     if (is_wait_for_receive) {
600       if(src_traced==MPI_ANY_SOURCE)
601         src_traced = (status != MPI_STATUS_IGNORE) ? comm->group()->rank(status->MPI_SOURCE) : src_traced;
602       TRACE_smpi_recv(src_traced, dst_traced, tag_traced);
603     }
604   }
605
606   smpi_bench_begin();
607   return retval;
608 }
609
610 int PMPI_Waitany(int count, MPI_Request requests[], int *index, MPI_Status * status)
611 {
612   if (index == nullptr)
613     return MPI_ERR_ARG;
614
615   if (count <= 0)
616     return MPI_SUCCESS;
617
618   smpi_bench_end();
619   //save requests information for tracing
620   struct savedvalstype {
621     int src;
622     int dst;
623     int recv;
624     int tag;
625     MPI_Comm comm;
626   };
627   savedvalstype* savedvals = xbt_new0(savedvalstype, count);
628
629   for (int i = 0; i < count; i++) {
630     MPI_Request req = requests[i];      //already received requests are no longer valid
631     if (req) {
632       savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), req->comm()};
633     }
634   }
635   int rank_traced = smpi_process()->index();
636   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
637   extra->type = TRACING_WAITANY;
638   extra->send_size=count;
639   TRACE_smpi_ptp_in(rank_traced, __FUNCTION__,extra);
640
641   *index = simgrid::smpi::Request::waitany(count, requests, status);
642
643   if(*index!=MPI_UNDEFINED){
644     int src_traced = savedvals[*index].src;
645     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
646     int dst_traced = savedvals[*index].dst;
647     int is_wait_for_receive = savedvals[*index].recv;
648     if (is_wait_for_receive) {
649       if(savedvals[*index].src==MPI_ANY_SOURCE)
650         src_traced = (status != MPI_STATUSES_IGNORE) ? savedvals[*index].comm->group()->rank(status->MPI_SOURCE)
651                                                      : savedvals[*index].src;
652       TRACE_smpi_recv(src_traced, dst_traced, savedvals[*index].tag);
653     }
654     TRACE_smpi_ptp_out(rank_traced);
655   }
656   xbt_free(savedvals);
657
658   smpi_bench_begin();
659   return MPI_SUCCESS;
660 }
661
662 int PMPI_Waitall(int count, MPI_Request requests[], MPI_Status status[])
663 {
664   smpi_bench_end();
665   //save information from requests
666   struct savedvalstype {
667     int src;
668     int dst;
669     int recv;
670     int tag;
671     int valid;
672     MPI_Comm comm;
673   };
674   savedvalstype* savedvals=xbt_new0(savedvalstype, count);
675
676   for (int i = 0; i < count; i++) {
677     MPI_Request req = requests[i];
678     if(req!=MPI_REQUEST_NULL){
679       savedvals[i]=(savedvalstype){req->src(), req->dst(), (req->flags() & RECV), req->tag(), 1, req->comm()};
680     }else{
681       savedvals[i].valid=0;
682     }
683   }
684   int rank_traced = smpi_process()->index();
685   instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
686   extra->type = TRACING_WAITALL;
687   extra->send_size=count;
688   TRACE_smpi_ptp_in(rank_traced, __FUNCTION__,extra);
689
690   int retval = simgrid::smpi::Request::waitall(count, requests, status);
691
692   for (int i = 0; i < count; i++) {
693     if(savedvals[i].valid){
694       // the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
695       int src_traced = savedvals[i].src;
696       int dst_traced = savedvals[i].dst;
697       int is_wait_for_receive = savedvals[i].recv;
698       if (is_wait_for_receive) {
699         if(src_traced==MPI_ANY_SOURCE)
700           src_traced = (status != MPI_STATUSES_IGNORE) ? savedvals[i].comm->group()->rank(status[i].MPI_SOURCE)
701                                                        : savedvals[i].src;
702         TRACE_smpi_recv(src_traced, dst_traced,savedvals[i].tag);
703       }
704     }
705   }
706   TRACE_smpi_ptp_out(rank_traced);
707   xbt_free(savedvals);
708
709   smpi_bench_begin();
710   return retval;
711 }
712
713 int PMPI_Waitsome(int incount, MPI_Request requests[], int *outcount, int *indices, MPI_Status status[])
714 {
715   int retval = 0;
716
717   smpi_bench_end();
718   if (outcount == nullptr) {
719     retval = MPI_ERR_ARG;
720   } else {
721     *outcount = simgrid::smpi::Request::waitsome(incount, requests, indices, status);
722     retval = MPI_SUCCESS;
723   }
724   smpi_bench_begin();
725   return retval;
726 }
727
728 int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indices, MPI_Status status[])
729 {
730   int retval = 0;
731
732   smpi_bench_end();
733   if (outcount == nullptr) {
734     retval = MPI_ERR_ARG;
735   } else {
736     *outcount = simgrid::smpi::Request::testsome(incount, requests, indices, status);
737     retval    = MPI_SUCCESS;
738   }
739   smpi_bench_begin();
740   return retval;
741 }
742
743 MPI_Request PMPI_Request_f2c(MPI_Fint request){
744   return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
745 }
746
747 MPI_Fint PMPI_Request_c2f(MPI_Request request) {
748   return request->c2f();
749 }
750
751 }