Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
codacy
[simgrid.git] / src / smpi / bindings / smpi_pmpi_win.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.h"
7 #include "smpi_comm.hpp"
8 #include "smpi_coll.hpp"
9 #include "smpi_datatype_derived.hpp"
10 #include "smpi_op.hpp"
11 #include "smpi_process.hpp"
12 #include "smpi_win.hpp"
13
14 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
15
16 /* PMPI User level calls */
17 extern "C" { // Obviously, the C MPI interface should use the C linkage
18
19 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
20   int retval = 0;
21   smpi_bench_end();
22   if (comm == MPI_COMM_NULL) {
23     retval= MPI_ERR_COMM;
24   }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
25     retval= MPI_ERR_OTHER;
26   }else{
27     *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
28     retval = MPI_SUCCESS;
29   }
30   smpi_bench_begin();
31   return retval;
32 }
33
34 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
35   int retval = 0;
36   smpi_bench_end();
37   if (comm == MPI_COMM_NULL) {
38     retval= MPI_ERR_COMM;
39   }else if (disp_unit <= 0 || size < 0 ){
40     retval= MPI_ERR_OTHER;
41   }else{
42     void* ptr = xbt_malloc(size);
43     if(ptr==nullptr)
44       return MPI_ERR_NO_MEM;
45     *static_cast<void**>(base) = ptr;
46     *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
47     retval = MPI_SUCCESS;
48   }
49   smpi_bench_begin();
50   return retval;
51 }
52
53 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
54   int retval = 0;
55   smpi_bench_end();
56   if (comm == MPI_COMM_NULL) {
57     retval= MPI_ERR_COMM;
58   }else{
59     *win = new simgrid::smpi::Win(info, comm);
60     retval = MPI_SUCCESS;
61   }
62   smpi_bench_begin();
63   return retval;
64 }
65
66 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
67   int retval = 0;
68   smpi_bench_end();
69   if(win == MPI_WIN_NULL){
70     retval = MPI_ERR_WIN;
71   } else if ((base == nullptr && size != 0) || size < 0 ){
72     retval= MPI_ERR_OTHER;
73   }else{
74     retval = win->attach(base, size);
75   }
76   smpi_bench_begin();
77   return retval;
78 }
79
80 int PMPI_Win_detach(MPI_Win win,  void *base){
81   int retval = 0;
82   smpi_bench_end();
83   if(win == MPI_WIN_NULL){
84     retval = MPI_ERR_WIN;
85   } else if (base == nullptr){
86     retval= MPI_ERR_OTHER;
87   }else{
88     retval = win->detach(base);
89   }
90   smpi_bench_begin();
91   return retval;
92 }
93
94
95 int PMPI_Win_free( MPI_Win* win){
96   int retval = 0;
97   smpi_bench_end();
98   if (win == nullptr || *win == MPI_WIN_NULL) {
99     retval = MPI_ERR_WIN;
100   }else{
101     delete *win;
102     retval=MPI_SUCCESS;
103   }
104   smpi_bench_begin();
105   return retval;
106 }
107
108 int PMPI_Win_set_name(MPI_Win  win, char * name)
109 {
110   if (win == MPI_WIN_NULL)  {
111     return MPI_ERR_TYPE;
112   } else if (name == nullptr)  {
113     return MPI_ERR_ARG;
114   } else {
115     win->set_name(name);
116     return MPI_SUCCESS;
117   }
118 }
119
120 int PMPI_Win_get_name(MPI_Win  win, char * name, int* len)
121 {
122   if (win == MPI_WIN_NULL)  {
123     return MPI_ERR_WIN;
124   } else if (name == nullptr)  {
125     return MPI_ERR_ARG;
126   } else {
127     win->get_name(name, len);
128     return MPI_SUCCESS;
129   }
130 }
131
132 int PMPI_Win_get_info(MPI_Win  win, MPI_Info* info)
133 {
134   if (win == MPI_WIN_NULL)  {
135     return MPI_ERR_WIN;
136   } else {
137     *info = win->info();
138     return MPI_SUCCESS;
139   }
140 }
141
142 int PMPI_Win_set_info(MPI_Win  win, MPI_Info info)
143 {
144   if (win == MPI_WIN_NULL)  {
145     return MPI_ERR_TYPE;
146   } else {
147     win->set_info(info);
148     return MPI_SUCCESS;
149   }
150 }
151
152 int PMPI_Win_get_group(MPI_Win  win, MPI_Group * group){
153   if (win == MPI_WIN_NULL)  {
154     return MPI_ERR_WIN;
155   }else {
156     win->get_group(group);
157     (*group)->ref();
158     return MPI_SUCCESS;
159   }
160 }
161
162 int PMPI_Win_fence( int assert,  MPI_Win win){
163   int retval = 0;
164   smpi_bench_end();
165   if (win == MPI_WIN_NULL) {
166     retval = MPI_ERR_WIN;
167   } else {
168   int rank = smpi_process()->index();
169   TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
170   retval = win->fence(assert);
171   TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
172   }
173   smpi_bench_begin();
174   return retval;
175 }
176
177 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
178               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
179   int retval = 0;
180   smpi_bench_end();
181   if (win == MPI_WIN_NULL) {
182     retval = MPI_ERR_WIN;
183   } else if (target_rank == MPI_PROC_NULL) {
184     retval = MPI_SUCCESS;
185   } else if (target_rank <0){
186     retval = MPI_ERR_RANK;
187   } else if (win->dynamic()==0 && target_disp <0){
188     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
189     retval = MPI_ERR_ARG;
190   } else if ((origin_count < 0 || target_count < 0) ||
191              (origin_addr==nullptr && origin_count > 0)){
192     retval = MPI_ERR_COUNT;
193   } else if ((not origin_datatype->is_valid()) || (not target_datatype->is_valid())) {
194     retval = MPI_ERR_TYPE;
195   } else {
196     int rank = smpi_process()->index();
197     MPI_Group group;
198     win->get_group(&group);
199     int src_traced = group->index(target_rank);
200     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
201
202     retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
203                            target_datatype);
204
205     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
206   }
207   smpi_bench_begin();
208   return retval;
209 }
210
211 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
212               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
213   int retval = 0;
214   smpi_bench_end();
215   if (win == MPI_WIN_NULL) {
216     retval = MPI_ERR_WIN;
217   } else if (target_rank == MPI_PROC_NULL) {
218     *request = MPI_REQUEST_NULL;
219     retval = MPI_SUCCESS;
220   } else if (target_rank <0){
221     retval = MPI_ERR_RANK;
222   } else if (win->dynamic()==0 && target_disp <0){
223     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
224     retval = MPI_ERR_ARG;
225   } else if ((origin_count < 0 || target_count < 0) ||
226              (origin_addr==nullptr && origin_count > 0)){
227     retval = MPI_ERR_COUNT;
228   } else if ((not origin_datatype->is_valid()) || (not target_datatype->is_valid())) {
229     retval = MPI_ERR_TYPE;
230   } else if(request == nullptr){
231     retval = MPI_ERR_REQUEST;
232   } else {
233     int rank = smpi_process()->index();
234     MPI_Group group;
235     win->get_group(&group);
236     int src_traced = group->index(target_rank);
237     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
238
239     retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
240                            target_datatype, request);
241
242     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
243   }
244   smpi_bench_begin();
245   return retval;
246 }
247
248 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
249               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
250   int retval = 0;
251   smpi_bench_end();
252   if (win == MPI_WIN_NULL) {
253     retval = MPI_ERR_WIN;
254   } else if (target_rank == MPI_PROC_NULL) {
255     retval = MPI_SUCCESS;
256   } else if (target_rank <0){
257     retval = MPI_ERR_RANK;
258   } else if (win->dynamic()==0 && target_disp <0){
259     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
260     retval = MPI_ERR_ARG;
261   } else if ((origin_count < 0 || target_count < 0) ||
262             (origin_addr==nullptr && origin_count > 0)){
263     retval = MPI_ERR_COUNT;
264   } else if ((not origin_datatype->is_valid()) || (not target_datatype->is_valid())) {
265     retval = MPI_ERR_TYPE;
266   } else {
267     int rank = smpi_process()->index();
268     MPI_Group group;
269     win->get_group(&group);
270     int dst_traced = group->index(target_rank);
271     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
272     TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
273
274     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
275                            target_datatype);
276
277     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
278   }
279   smpi_bench_begin();
280   return retval;
281 }
282
283 int PMPI_Rput( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
284               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
285   int retval = 0;
286   smpi_bench_end();
287   if (win == MPI_WIN_NULL) {
288     retval = MPI_ERR_WIN;
289   } else if (target_rank == MPI_PROC_NULL) {
290     *request = MPI_REQUEST_NULL;
291     retval = MPI_SUCCESS;
292   } else if (target_rank <0){
293     retval = MPI_ERR_RANK;
294   } else if (win->dynamic()==0 && target_disp <0){
295     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
296     retval = MPI_ERR_ARG;
297   } else if ((origin_count < 0 || target_count < 0) ||
298             (origin_addr==nullptr && origin_count > 0)){
299     retval = MPI_ERR_COUNT;
300   } else if ((not origin_datatype->is_valid()) || (not target_datatype->is_valid())) {
301     retval = MPI_ERR_TYPE;
302   } else if(request == nullptr){
303     retval = MPI_ERR_REQUEST;
304   } else {
305     int rank = smpi_process()->index();
306     MPI_Group group;
307     win->get_group(&group);
308     int dst_traced = group->index(target_rank);
309     TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, nullptr);
310     TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
311
312     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
313                            target_datatype, request);
314
315     TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
316   }
317   smpi_bench_begin();
318   return retval;
319 }
320
321 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
322               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
323   int retval = 0;
324   smpi_bench_end();
325   if (win == MPI_WIN_NULL) {
326     retval = MPI_ERR_WIN;
327   } else if (target_rank == MPI_PROC_NULL) {
328     retval = MPI_SUCCESS;
329   } else if (target_rank <0){
330     retval = MPI_ERR_RANK;
331   } else if (win->dynamic()==0 && target_disp <0){
332     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
333     retval = MPI_ERR_ARG;
334   } else if ((origin_count < 0 || target_count < 0) ||
335              (origin_addr==nullptr && origin_count > 0)){
336     retval = MPI_ERR_COUNT;
337   } else if ((not origin_datatype->is_valid()) || (not target_datatype->is_valid())) {
338     retval = MPI_ERR_TYPE;
339   } else if (op == MPI_OP_NULL) {
340     retval = MPI_ERR_OP;
341   } else {
342     int rank = smpi_process()->index();
343     MPI_Group group;
344     win->get_group(&group);
345     int src_traced = group->index(target_rank);
346     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
347
348     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
349                                   target_datatype, op);
350
351     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
352   }
353   smpi_bench_begin();
354   return retval;
355 }
356
357 int PMPI_Raccumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
358               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
359   int retval = 0;
360   smpi_bench_end();
361   if (win == MPI_WIN_NULL) {
362     retval = MPI_ERR_WIN;
363   } else if (target_rank == MPI_PROC_NULL) {
364     *request = MPI_REQUEST_NULL;
365     retval = MPI_SUCCESS;
366   } else if (target_rank <0){
367     retval = MPI_ERR_RANK;
368   } else if (win->dynamic()==0 && target_disp <0){
369     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
370     retval = MPI_ERR_ARG;
371   } else if ((origin_count < 0 || target_count < 0) ||
372              (origin_addr==nullptr && origin_count > 0)){
373     retval = MPI_ERR_COUNT;
374   } else if ((not origin_datatype->is_valid()) || (not target_datatype->is_valid())) {
375     retval = MPI_ERR_TYPE;
376   } else if (op == MPI_OP_NULL) {
377     retval = MPI_ERR_OP;
378   } else if(request == nullptr){
379     retval = MPI_ERR_REQUEST;
380   } else {
381     int rank = smpi_process()->index();
382     MPI_Group group;
383     win->get_group(&group);
384     int src_traced = group->index(target_rank);
385     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
386
387     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
388                                   target_datatype, op, request);
389
390     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
391   }
392   smpi_bench_begin();
393   return retval;
394 }
395
396 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
397 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
398 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
399   int retval = 0;
400   smpi_bench_end();
401   if (win == MPI_WIN_NULL) {
402     retval = MPI_ERR_WIN;
403   } else if (target_rank == MPI_PROC_NULL) {
404     retval = MPI_SUCCESS;
405   } else if (target_rank <0){
406     retval = MPI_ERR_RANK;
407   } else if (win->dynamic()==0 && target_disp <0){
408     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
409     retval = MPI_ERR_ARG;
410   } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
411              (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
412              (result_addr==nullptr && result_count > 0)){
413     retval = MPI_ERR_COUNT;
414   } else if ((origin_datatype != MPI_DATATYPE_NULL && not origin_datatype->is_valid()) ||
415              (not target_datatype->is_valid()) || (not result_datatype->is_valid())) {
416     retval = MPI_ERR_TYPE;
417   } else if (op == MPI_OP_NULL) {
418     retval = MPI_ERR_OP;
419   } else {
420     int rank = smpi_process()->index();
421     MPI_Group group;
422     win->get_group(&group);
423     int src_traced = group->index(target_rank);
424     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
425
426     retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
427                                   result_count, result_datatype, target_rank, target_disp,
428                                   target_count, target_datatype, op);
429
430     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
431   }
432   smpi_bench_begin();
433   return retval;
434 }
435
436
437 int PMPI_Rget_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
438 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
439 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
440   int retval = 0;
441   smpi_bench_end();
442   if (win == MPI_WIN_NULL) {
443     retval = MPI_ERR_WIN;
444   } else if (target_rank == MPI_PROC_NULL) {
445     *request = MPI_REQUEST_NULL;
446     retval = MPI_SUCCESS;
447   } else if (target_rank <0){
448     retval = MPI_ERR_RANK;
449   } else if (win->dynamic()==0 && target_disp <0){
450     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
451     retval = MPI_ERR_ARG;
452   } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
453              (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
454              (result_addr==nullptr && result_count > 0)){
455     retval = MPI_ERR_COUNT;
456   } else if ((origin_datatype != MPI_DATATYPE_NULL && not origin_datatype->is_valid()) ||
457              (not target_datatype->is_valid()) || (not result_datatype->is_valid())) {
458     retval = MPI_ERR_TYPE;
459   } else if (op == MPI_OP_NULL) {
460     retval = MPI_ERR_OP;
461   } else if(request == nullptr){
462     retval = MPI_ERR_REQUEST;
463   } else {
464     int rank = smpi_process()->index();
465     MPI_Group group;
466     win->get_group(&group);
467     int src_traced = group->index(target_rank);
468     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
469
470     retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
471                                   result_count, result_datatype, target_rank, target_disp,
472                                   target_count, target_datatype, op, request);
473
474     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
475   }
476   smpi_bench_begin();
477   return retval;
478 }
479
480 int PMPI_Fetch_and_op(void *origin_addr, void *result_addr, MPI_Datatype dtype, int target_rank, MPI_Aint target_disp, MPI_Op op, MPI_Win win){
481   return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
482 }
483
484 int PMPI_Compare_and_swap(void *origin_addr, void *compare_addr,
485         void *result_addr, MPI_Datatype datatype, int target_rank,
486         MPI_Aint target_disp, MPI_Win win){
487   int retval = 0;
488   smpi_bench_end();
489   if (win == MPI_WIN_NULL) {
490     retval = MPI_ERR_WIN;
491   } else if (target_rank == MPI_PROC_NULL) {
492     retval = MPI_SUCCESS;
493   } else if (target_rank <0){
494     retval = MPI_ERR_RANK;
495   } else if (win->dynamic()==0 && target_disp <0){
496     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
497     retval = MPI_ERR_ARG;
498   } else if (origin_addr==nullptr || result_addr==nullptr || compare_addr==nullptr){
499     retval = MPI_ERR_COUNT;
500   } else if (not datatype->is_valid()) {
501     retval = MPI_ERR_TYPE;
502   } else {
503     int rank = smpi_process()->index();
504     MPI_Group group;
505     win->get_group(&group);
506     int src_traced = group->index(target_rank);
507     TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, nullptr);
508
509     retval = win->compare_and_swap( origin_addr, compare_addr, result_addr, datatype,
510                                   target_rank, target_disp);
511
512     TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
513   }
514   smpi_bench_begin();
515   return retval;
516 }
517
518 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
519   int retval = 0;
520   smpi_bench_end();
521   if (win == MPI_WIN_NULL) {
522     retval = MPI_ERR_WIN;
523   } else if (group==MPI_GROUP_NULL){
524     retval = MPI_ERR_GROUP;
525   } else {
526     int rank = smpi_process()->index();
527     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
528     retval = win->post(group,assert);
529     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
530   }
531   smpi_bench_begin();
532   return retval;
533 }
534
535 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
536   int retval = 0;
537   smpi_bench_end();
538   if (win == MPI_WIN_NULL) {
539     retval = MPI_ERR_WIN;
540   } else if (group==MPI_GROUP_NULL){
541     retval = MPI_ERR_GROUP;
542   } else {
543     int rank = smpi_process()->index();
544     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
545     retval = win->start(group,assert);
546     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
547   }
548   smpi_bench_begin();
549   return retval;
550 }
551
552 int PMPI_Win_complete(MPI_Win win){
553   int retval = 0;
554   smpi_bench_end();
555   if (win == MPI_WIN_NULL) {
556     retval = MPI_ERR_WIN;
557   } else {
558     int rank = smpi_process()->index();
559     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
560
561     retval = win->complete();
562
563     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
564   }
565   smpi_bench_begin();
566   return retval;
567 }
568
569 int PMPI_Win_wait(MPI_Win win){
570   int retval = 0;
571   smpi_bench_end();
572   if (win == MPI_WIN_NULL) {
573     retval = MPI_ERR_WIN;
574   } else {
575     int rank = smpi_process()->index();
576     TRACE_smpi_collective_in(rank, -1, __FUNCTION__, nullptr);
577
578     retval = win->wait();
579
580     TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
581   }
582   smpi_bench_begin();
583   return retval;
584 }
585
586 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
587   int retval = 0;
588   smpi_bench_end();
589   if (win == MPI_WIN_NULL) {
590     retval = MPI_ERR_WIN;
591   } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
592              lock_type != MPI_LOCK_SHARED) {
593     retval = MPI_ERR_LOCKTYPE;
594   } else if (rank == MPI_PROC_NULL){
595     retval = MPI_SUCCESS;
596   } else {
597     int myrank = smpi_process()->index();
598     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
599     retval = win->lock(lock_type,rank,assert);
600     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
601   }
602   smpi_bench_begin();
603   return retval;
604 }
605
606 int PMPI_Win_unlock(int rank, MPI_Win win){
607   int retval = 0;
608   smpi_bench_end();
609   if (win == MPI_WIN_NULL) {
610     retval = MPI_ERR_WIN;
611   } else if (rank == MPI_PROC_NULL){
612     retval = MPI_SUCCESS;
613   } else {
614     int myrank = smpi_process()->index();
615     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
616     retval = win->unlock(rank);
617     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
618   }
619   smpi_bench_begin();
620   return retval;
621 }
622
623 int PMPI_Win_lock_all(int assert, MPI_Win win){
624   int retval = 0;
625   smpi_bench_end();
626   if (win == MPI_WIN_NULL) {
627     retval = MPI_ERR_WIN;
628   } else {
629     int myrank = smpi_process()->index();
630     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
631     retval = win->lock_all(assert);
632     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
633   }
634   smpi_bench_begin();
635   return retval;
636 }
637
638 int PMPI_Win_unlock_all(MPI_Win win){
639   int retval = 0;
640   smpi_bench_end();
641   if (win == MPI_WIN_NULL) {
642     retval = MPI_ERR_WIN;
643   } else {
644     int myrank = smpi_process()->index();
645     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
646     retval = win->unlock_all();
647     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
648   }
649   smpi_bench_begin();
650   return retval;
651 }
652
653 int PMPI_Win_flush(int rank, MPI_Win win){
654   int retval = 0;
655   smpi_bench_end();
656   if (win == MPI_WIN_NULL) {
657     retval = MPI_ERR_WIN;
658   } else if (rank == MPI_PROC_NULL){
659     retval = MPI_SUCCESS;
660   } else {
661     int myrank = smpi_process()->index();
662     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
663     retval = win->flush(rank);
664     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
665   }
666   smpi_bench_begin();
667   return retval;
668 }
669
670 int PMPI_Win_flush_local(int rank, MPI_Win win){
671   int retval = 0;
672   smpi_bench_end();
673   if (win == MPI_WIN_NULL) {
674     retval = MPI_ERR_WIN;
675   } else if (rank == MPI_PROC_NULL){
676     retval = MPI_SUCCESS;
677   } else {
678     int myrank = smpi_process()->index();
679     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
680     retval = win->flush_local(rank);
681     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
682   }
683   smpi_bench_begin();
684   return retval;
685 }
686
687 int PMPI_Win_flush_all(MPI_Win win){
688   int retval = 0;
689   smpi_bench_end();
690   if (win == MPI_WIN_NULL) {
691     retval = MPI_ERR_WIN;
692   } else {
693     int myrank = smpi_process()->index();
694     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
695     retval = win->flush_all();
696     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
697   }
698   smpi_bench_begin();
699   return retval;
700 }
701
702 int PMPI_Win_flush_local_all(MPI_Win win){
703   int retval = 0;
704   smpi_bench_end();
705   if (win == MPI_WIN_NULL) {
706     retval = MPI_ERR_WIN;
707   } else {
708     int myrank = smpi_process()->index();
709     TRACE_smpi_collective_in(myrank, -1, __FUNCTION__, nullptr);
710     retval = win->flush_local_all();
711     TRACE_smpi_collective_out(myrank, -1, __FUNCTION__);
712   }
713   smpi_bench_begin();
714   return retval;
715 }
716
717
718 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
719 {
720   static MPI_Aint size;
721   static int disp_unit;
722   if (win==MPI_WIN_NULL)
723     return MPI_ERR_TYPE;
724   else{
725   switch (keyval) {
726     case MPI_WIN_BASE :
727       *static_cast<void**>(attribute_val)  = win->base();
728       *flag = 1;
729       return MPI_SUCCESS;
730     case MPI_WIN_SIZE :
731       size = win->size();
732       *static_cast<MPI_Aint**>(attribute_val)  = &size;
733       *flag = 1;
734       return MPI_SUCCESS;
735     case MPI_WIN_DISP_UNIT :
736       disp_unit=win->disp_unit();
737       *static_cast<int**>(attribute_val)  = &disp_unit;
738       *flag = 1;
739       return MPI_SUCCESS;
740     default:
741       return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
742   }
743 }
744
745 }
746
747 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
748 {
749   if (win==MPI_WIN_NULL)
750     return MPI_ERR_TYPE;
751   else
752     return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
753 }
754
755 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
756 {
757   if (win==MPI_WIN_NULL)
758     return MPI_ERR_TYPE;
759   else
760     return win->attr_delete<simgrid::smpi::Win>(type_keyval);
761 }
762
763 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
764                             void* extra_state)
765 {
766   smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
767   smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
768   return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
769 }
770
771 int PMPI_Win_free_keyval(int* keyval) {
772   return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
773 }
774
775 MPI_Win PMPI_Win_f2c(MPI_Fint win){
776   return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
777 }
778
779 MPI_Fint PMPI_Win_c2f(MPI_Win win){
780   return win->c2f();
781 }
782
783 }