Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Rename C++ only header files from .h to .hpp.
[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, __FUNCTION__, nullptr);
170   retval = win->fence(assert);
171   TRACE_smpi_collective_out(rank, __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 (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
194             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
195     retval = MPI_ERR_TYPE;
196   } else {
197     int rank = smpi_process()->index();
198     MPI_Group group;
199     win->get_group(&group);
200     TRACE_smpi_ptp_in(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, 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 (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
229             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
230     retval = MPI_ERR_TYPE;
231   } else if(request == nullptr){
232     retval = MPI_ERR_REQUEST;
233   } else {
234     int rank = smpi_process()->index();
235     MPI_Group group;
236     win->get_group(&group);
237     TRACE_smpi_ptp_in(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, 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 (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
265             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
266     retval = MPI_ERR_TYPE;
267   } else {
268     int rank = smpi_process()->index();
269     MPI_Group group;
270     win->get_group(&group);
271     int dst_traced = group->index(target_rank);
272     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
273     TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
274
275     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
276                            target_datatype);
277
278     TRACE_smpi_ptp_out(rank, dst_traced, __FUNCTION__);
279   }
280   smpi_bench_begin();
281   return retval;
282 }
283
284 int PMPI_Rput( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
285               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
286   int retval = 0;
287   smpi_bench_end();
288   if (win == MPI_WIN_NULL) {
289     retval = MPI_ERR_WIN;
290   } else if (target_rank == MPI_PROC_NULL) {
291     *request = MPI_REQUEST_NULL;
292     retval = MPI_SUCCESS;
293   } else if (target_rank <0){
294     retval = MPI_ERR_RANK;
295   } else if (win->dynamic()==0 && target_disp <0){
296     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
297     retval = MPI_ERR_ARG;
298   } else if ((origin_count < 0 || target_count < 0) ||
299             (origin_addr==nullptr && origin_count > 0)){
300     retval = MPI_ERR_COUNT;
301   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
302             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
303     retval = MPI_ERR_TYPE;
304   } else if(request == nullptr){
305     retval = MPI_ERR_REQUEST;
306   } else {
307     int rank = smpi_process()->index();
308     MPI_Group group;
309     win->get_group(&group);
310     int dst_traced = group->index(target_rank);
311     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
312     TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
313
314     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
315                            target_datatype, request);
316
317     TRACE_smpi_ptp_out(rank, dst_traced, __FUNCTION__);
318   }
319   smpi_bench_begin();
320   return retval;
321 }
322
323 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
324               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
325   int retval = 0;
326   smpi_bench_end();
327   if (win == MPI_WIN_NULL) {
328     retval = MPI_ERR_WIN;
329   } else if (target_rank == MPI_PROC_NULL) {
330     retval = MPI_SUCCESS;
331   } else if (target_rank <0){
332     retval = MPI_ERR_RANK;
333   } else if (win->dynamic()==0 && target_disp <0){
334     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
335     retval = MPI_ERR_ARG;
336   } else if ((origin_count < 0 || target_count < 0) ||
337              (origin_addr==nullptr && origin_count > 0)){
338     retval = MPI_ERR_COUNT;
339   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
340             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
341     retval = MPI_ERR_TYPE;
342   } else if (op == MPI_OP_NULL) {
343     retval = MPI_ERR_OP;
344   } else {
345     int rank = smpi_process()->index();
346     MPI_Group group;
347     win->get_group(&group);
348     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
349     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
350                                   target_datatype, op);
351
352     TRACE_smpi_ptp_out(rank, rank, __FUNCTION__);
353   }
354   smpi_bench_begin();
355   return retval;
356 }
357
358 int PMPI_Raccumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
359               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
360   int retval = 0;
361   smpi_bench_end();
362   if (win == MPI_WIN_NULL) {
363     retval = MPI_ERR_WIN;
364   } else if (target_rank == MPI_PROC_NULL) {
365     *request = MPI_REQUEST_NULL;
366     retval = MPI_SUCCESS;
367   } else if (target_rank <0){
368     retval = MPI_ERR_RANK;
369   } else if (win->dynamic()==0 && target_disp <0){
370     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
371     retval = MPI_ERR_ARG;
372   } else if ((origin_count < 0 || target_count < 0) ||
373              (origin_addr==nullptr && origin_count > 0)){
374     retval = MPI_ERR_COUNT;
375   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
376             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
377     retval = MPI_ERR_TYPE;
378   } else if (op == MPI_OP_NULL) {
379     retval = MPI_ERR_OP;
380   } else if(request == nullptr){
381     retval = MPI_ERR_REQUEST;
382   } else {
383     int rank = smpi_process()->index();
384     MPI_Group group;
385     win->get_group(&group);
386     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
387
388     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
389                                   target_datatype, op, request);
390
391     TRACE_smpi_ptp_out(rank, rank, __FUNCTION__);
392   }
393   smpi_bench_begin();
394   return retval;
395 }
396
397 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
398 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
399 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
400   int retval = 0;
401   smpi_bench_end();
402   if (win == MPI_WIN_NULL) {
403     retval = MPI_ERR_WIN;
404   } else if (target_rank == MPI_PROC_NULL) {
405     retval = MPI_SUCCESS;
406   } else if (target_rank <0){
407     retval = MPI_ERR_RANK;
408   } else if (win->dynamic()==0 && target_disp <0){
409     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
410     retval = MPI_ERR_ARG;
411   } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
412              (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
413              (result_addr==nullptr && result_count > 0)){
414     retval = MPI_ERR_COUNT;
415   } else if (((target_datatype == MPI_DATATYPE_NULL) || (result_datatype == MPI_DATATYPE_NULL)) ||
416             (((origin_datatype != MPI_DATATYPE_NULL) && (not origin_datatype->is_valid())) || (not target_datatype->is_valid()) || (not result_datatype->is_valid()))) {
417     retval = MPI_ERR_TYPE;
418   } else if (op == MPI_OP_NULL) {
419     retval = MPI_ERR_OP;
420   } else {
421     int rank = smpi_process()->index();
422     MPI_Group group;
423     win->get_group(&group);
424     TRACE_smpi_ptp_in(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, 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 (((target_datatype == MPI_DATATYPE_NULL) || (result_datatype == MPI_DATATYPE_NULL)) ||
457             (((origin_datatype != MPI_DATATYPE_NULL) && (not origin_datatype->is_valid())) || (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     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
468
469     retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
470                                   result_count, result_datatype, target_rank, target_disp,
471                                   target_count, target_datatype, op, request);
472
473     TRACE_smpi_ptp_out(rank, rank, __FUNCTION__);
474   }
475   smpi_bench_begin();
476   return retval;
477 }
478
479 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){
480   return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
481 }
482
483 int PMPI_Compare_and_swap(void *origin_addr, void *compare_addr,
484         void *result_addr, MPI_Datatype datatype, int target_rank,
485         MPI_Aint target_disp, MPI_Win win){
486   int retval = 0;
487   smpi_bench_end();
488   if (win == MPI_WIN_NULL) {
489     retval = MPI_ERR_WIN;
490   } else if (target_rank == MPI_PROC_NULL) {
491     retval = MPI_SUCCESS;
492   } else if (target_rank <0){
493     retval = MPI_ERR_RANK;
494   } else if (win->dynamic()==0 && target_disp <0){
495     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
496     retval = MPI_ERR_ARG;
497   } else if (origin_addr==nullptr || result_addr==nullptr || compare_addr==nullptr){
498     retval = MPI_ERR_COUNT;
499   } else if ((datatype == MPI_DATATYPE_NULL) || (not datatype->is_valid())) {
500     retval = MPI_ERR_TYPE;
501   } else {
502     int rank = smpi_process()->index();
503     MPI_Group group;
504     win->get_group(&group);
505     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
506
507     retval = win->compare_and_swap( origin_addr, compare_addr, result_addr, datatype,
508                                   target_rank, target_disp);
509
510     TRACE_smpi_ptp_out(rank, rank, __FUNCTION__);
511   }
512   smpi_bench_begin();
513   return retval;
514 }
515
516 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
517   int retval = 0;
518   smpi_bench_end();
519   if (win == MPI_WIN_NULL) {
520     retval = MPI_ERR_WIN;
521   } else if (group==MPI_GROUP_NULL){
522     retval = MPI_ERR_GROUP;
523   } else {
524     int rank = smpi_process()->index();
525     TRACE_smpi_collective_in(rank, __FUNCTION__, nullptr);
526     retval = win->post(group,assert);
527     TRACE_smpi_collective_out(rank, __FUNCTION__);
528   }
529   smpi_bench_begin();
530   return retval;
531 }
532
533 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
534   int retval = 0;
535   smpi_bench_end();
536   if (win == MPI_WIN_NULL) {
537     retval = MPI_ERR_WIN;
538   } else if (group==MPI_GROUP_NULL){
539     retval = MPI_ERR_GROUP;
540   } else {
541     int rank = smpi_process()->index();
542     TRACE_smpi_collective_in(rank, __FUNCTION__, nullptr);
543     retval = win->start(group,assert);
544     TRACE_smpi_collective_out(rank, __FUNCTION__);
545   }
546   smpi_bench_begin();
547   return retval;
548 }
549
550 int PMPI_Win_complete(MPI_Win win){
551   int retval = 0;
552   smpi_bench_end();
553   if (win == MPI_WIN_NULL) {
554     retval = MPI_ERR_WIN;
555   } else {
556     int rank = smpi_process()->index();
557     TRACE_smpi_collective_in(rank, __FUNCTION__, nullptr);
558
559     retval = win->complete();
560
561     TRACE_smpi_collective_out(rank, __FUNCTION__);
562   }
563   smpi_bench_begin();
564   return retval;
565 }
566
567 int PMPI_Win_wait(MPI_Win win){
568   int retval = 0;
569   smpi_bench_end();
570   if (win == MPI_WIN_NULL) {
571     retval = MPI_ERR_WIN;
572   } else {
573     int rank = smpi_process()->index();
574     TRACE_smpi_collective_in(rank, __FUNCTION__, nullptr);
575
576     retval = win->wait();
577
578     TRACE_smpi_collective_out(rank, __FUNCTION__);
579   }
580   smpi_bench_begin();
581   return retval;
582 }
583
584 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
585   int retval = 0;
586   smpi_bench_end();
587   if (win == MPI_WIN_NULL) {
588     retval = MPI_ERR_WIN;
589   } else if (lock_type != MPI_LOCK_EXCLUSIVE &&
590              lock_type != MPI_LOCK_SHARED) {
591     retval = MPI_ERR_LOCKTYPE;
592   } else if (rank == MPI_PROC_NULL){
593     retval = MPI_SUCCESS;
594   } else {
595     int myrank = smpi_process()->index();
596     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
597     retval = win->lock(lock_type,rank,assert);
598     TRACE_smpi_collective_out(myrank, __FUNCTION__);
599   }
600   smpi_bench_begin();
601   return retval;
602 }
603
604 int PMPI_Win_unlock(int rank, MPI_Win win){
605   int retval = 0;
606   smpi_bench_end();
607   if (win == MPI_WIN_NULL) {
608     retval = MPI_ERR_WIN;
609   } else if (rank == MPI_PROC_NULL){
610     retval = MPI_SUCCESS;
611   } else {
612     int myrank = smpi_process()->index();
613     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
614     retval = win->unlock(rank);
615     TRACE_smpi_collective_out(myrank, __FUNCTION__);
616   }
617   smpi_bench_begin();
618   return retval;
619 }
620
621 int PMPI_Win_lock_all(int assert, MPI_Win win){
622   int retval = 0;
623   smpi_bench_end();
624   if (win == MPI_WIN_NULL) {
625     retval = MPI_ERR_WIN;
626   } else {
627     int myrank = smpi_process()->index();
628     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
629     retval = win->lock_all(assert);
630     TRACE_smpi_collective_out(myrank, __FUNCTION__);
631   }
632   smpi_bench_begin();
633   return retval;
634 }
635
636 int PMPI_Win_unlock_all(MPI_Win win){
637   int retval = 0;
638   smpi_bench_end();
639   if (win == MPI_WIN_NULL) {
640     retval = MPI_ERR_WIN;
641   } else {
642     int myrank = smpi_process()->index();
643     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
644     retval = win->unlock_all();
645     TRACE_smpi_collective_out(myrank, __FUNCTION__);
646   }
647   smpi_bench_begin();
648   return retval;
649 }
650
651 int PMPI_Win_flush(int rank, MPI_Win win){
652   int retval = 0;
653   smpi_bench_end();
654   if (win == MPI_WIN_NULL) {
655     retval = MPI_ERR_WIN;
656   } else if (rank == MPI_PROC_NULL){
657     retval = MPI_SUCCESS;
658   } else {
659     int myrank = smpi_process()->index();
660     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
661     retval = win->flush(rank);
662     TRACE_smpi_collective_out(myrank, __FUNCTION__);
663   }
664   smpi_bench_begin();
665   return retval;
666 }
667
668 int PMPI_Win_flush_local(int rank, MPI_Win win){
669   int retval = 0;
670   smpi_bench_end();
671   if (win == MPI_WIN_NULL) {
672     retval = MPI_ERR_WIN;
673   } else if (rank == MPI_PROC_NULL){
674     retval = MPI_SUCCESS;
675   } else {
676     int myrank = smpi_process()->index();
677     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
678     retval = win->flush_local(rank);
679     TRACE_smpi_collective_out(myrank, __FUNCTION__);
680   }
681   smpi_bench_begin();
682   return retval;
683 }
684
685 int PMPI_Win_flush_all(MPI_Win win){
686   int retval = 0;
687   smpi_bench_end();
688   if (win == MPI_WIN_NULL) {
689     retval = MPI_ERR_WIN;
690   } else {
691     int myrank = smpi_process()->index();
692     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
693     retval = win->flush_all();
694     TRACE_smpi_collective_out(myrank, __FUNCTION__);
695   }
696   smpi_bench_begin();
697   return retval;
698 }
699
700 int PMPI_Win_flush_local_all(MPI_Win win){
701   int retval = 0;
702   smpi_bench_end();
703   if (win == MPI_WIN_NULL) {
704     retval = MPI_ERR_WIN;
705   } else {
706     int myrank = smpi_process()->index();
707     TRACE_smpi_collective_in(myrank, __FUNCTION__, nullptr);
708     retval = win->flush_local_all();
709     TRACE_smpi_collective_out(myrank, __FUNCTION__);
710   }
711   smpi_bench_begin();
712   return retval;
713 }
714
715
716 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
717 {
718   static MPI_Aint size;
719   static int disp_unit;
720   if (win==MPI_WIN_NULL)
721     return MPI_ERR_TYPE;
722   else{
723   switch (keyval) {
724     case MPI_WIN_BASE :
725       *static_cast<void**>(attribute_val)  = win->base();
726       *flag = 1;
727       return MPI_SUCCESS;
728     case MPI_WIN_SIZE :
729       size = win->size();
730       *static_cast<MPI_Aint**>(attribute_val)  = &size;
731       *flag = 1;
732       return MPI_SUCCESS;
733     case MPI_WIN_DISP_UNIT :
734       disp_unit=win->disp_unit();
735       *static_cast<int**>(attribute_val)  = &disp_unit;
736       *flag = 1;
737       return MPI_SUCCESS;
738     default:
739       return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
740   }
741 }
742
743 }
744
745 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
746 {
747   if (win==MPI_WIN_NULL)
748     return MPI_ERR_TYPE;
749   else
750     return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
751 }
752
753 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
754 {
755   if (win==MPI_WIN_NULL)
756     return MPI_ERR_TYPE;
757   else
758     return win->attr_delete<simgrid::smpi::Win>(type_keyval);
759 }
760
761 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
762                             void* extra_state)
763 {
764   smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
765   smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
766   return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
767 }
768
769 int PMPI_Win_free_keyval(int* keyval) {
770   return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
771 }
772
773 MPI_Win PMPI_Win_f2c(MPI_Fint win){
774   return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
775 }
776
777 MPI_Fint PMPI_Win_c2f(MPI_Win win){
778   return win->c2f();
779 }
780
781 }