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_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.hpp"
7 #include "smpi_coll.hpp"
8 #include "smpi_comm.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 {
82   int retval = 0;
83   smpi_bench_end();
84   if(win == MPI_WIN_NULL){
85     retval = MPI_ERR_WIN;
86   } else if (base == nullptr){
87     retval= MPI_ERR_OTHER;
88   }else{
89     retval = win->detach(base);
90   }
91   smpi_bench_begin();
92   return retval;
93 }
94
95
96 int PMPI_Win_free( MPI_Win* win){
97   int retval = 0;
98   smpi_bench_end();
99   if (win == nullptr || *win == MPI_WIN_NULL) {
100     retval = MPI_ERR_WIN;
101   }else{
102     delete *win;
103     retval=MPI_SUCCESS;
104   }
105   smpi_bench_begin();
106   return retval;
107 }
108
109 int PMPI_Win_set_name(MPI_Win  win, char * name)
110 {
111   if (win == MPI_WIN_NULL)  {
112     return MPI_ERR_TYPE;
113   } else if (name == nullptr)  {
114     return MPI_ERR_ARG;
115   } else {
116     win->set_name(name);
117     return MPI_SUCCESS;
118   }
119 }
120
121 int PMPI_Win_get_name(MPI_Win  win, char * name, int* len)
122 {
123   if (win == MPI_WIN_NULL)  {
124     return MPI_ERR_WIN;
125   } else if (name == nullptr)  {
126     return MPI_ERR_ARG;
127   } else {
128     win->get_name(name, len);
129     return MPI_SUCCESS;
130   }
131 }
132
133 int PMPI_Win_get_info(MPI_Win  win, MPI_Info* info)
134 {
135   if (win == MPI_WIN_NULL)  {
136     return MPI_ERR_WIN;
137   } else {
138     *info = win->info();
139     return MPI_SUCCESS;
140   }
141 }
142
143 int PMPI_Win_set_info(MPI_Win  win, MPI_Info info)
144 {
145   if (win == MPI_WIN_NULL)  {
146     return MPI_ERR_TYPE;
147   } else {
148     win->set_info(info);
149     return MPI_SUCCESS;
150   }
151 }
152
153 int PMPI_Win_get_group(MPI_Win  win, MPI_Group * group){
154   if (win == MPI_WIN_NULL)  {
155     return MPI_ERR_WIN;
156   }else {
157     win->get_group(group);
158     (*group)->ref();
159     return MPI_SUCCESS;
160   }
161 }
162
163 int PMPI_Win_fence( int assert,  MPI_Win win){
164   int retval = 0;
165   smpi_bench_end();
166   if (win == MPI_WIN_NULL) {
167     retval = MPI_ERR_WIN;
168   } else {
169   int rank = smpi_process()->index();
170   TRACE_smpi_collective_in(rank, __FUNCTION__, nullptr);
171   retval = win->fence(assert);
172   TRACE_smpi_collective_out(rank);
173   }
174   smpi_bench_begin();
175   return retval;
176 }
177
178 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
179               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
180   int retval = 0;
181   smpi_bench_end();
182   if (win == MPI_WIN_NULL) {
183     retval = MPI_ERR_WIN;
184   } else if (target_rank == MPI_PROC_NULL) {
185     retval = MPI_SUCCESS;
186   } else if (target_rank <0){
187     retval = MPI_ERR_RANK;
188   } else if (win->dynamic()==0 && target_disp <0){
189     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
190     retval = MPI_ERR_ARG;
191   } else if ((origin_count < 0 || target_count < 0) ||
192              (origin_addr==nullptr && origin_count > 0)){
193     retval = MPI_ERR_COUNT;
194   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
195             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
196     retval = MPI_ERR_TYPE;
197   } else {
198     int rank = smpi_process()->index();
199     MPI_Group group;
200     win->get_group(&group);
201     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
202
203     retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
204                            target_datatype);
205
206     TRACE_smpi_ptp_out(rank);
207   }
208   smpi_bench_begin();
209   return retval;
210 }
211
212 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
213               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
214   int retval = 0;
215   smpi_bench_end();
216   if (win == MPI_WIN_NULL) {
217     retval = MPI_ERR_WIN;
218   } else if (target_rank == MPI_PROC_NULL) {
219     *request = MPI_REQUEST_NULL;
220     retval = MPI_SUCCESS;
221   } else if (target_rank <0){
222     retval = MPI_ERR_RANK;
223   } else if (win->dynamic()==0 && target_disp <0){
224     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
225     retval = MPI_ERR_ARG;
226   } else if ((origin_count < 0 || target_count < 0) ||
227              (origin_addr==nullptr && origin_count > 0)){
228     retval = MPI_ERR_COUNT;
229   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
230             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
231     retval = MPI_ERR_TYPE;
232   } else if(request == nullptr){
233     retval = MPI_ERR_REQUEST;
234   } else {
235     int rank = smpi_process()->index();
236     MPI_Group group;
237     win->get_group(&group);
238     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
239
240     retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
241                            target_datatype, request);
242
243     TRACE_smpi_ptp_out(rank);
244   }
245   smpi_bench_begin();
246   return retval;
247 }
248
249 int PMPI_Put( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
250               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
251   int retval = 0;
252   smpi_bench_end();
253   if (win == MPI_WIN_NULL) {
254     retval = MPI_ERR_WIN;
255   } else if (target_rank == MPI_PROC_NULL) {
256     retval = MPI_SUCCESS;
257   } else if (target_rank <0){
258     retval = MPI_ERR_RANK;
259   } else if (win->dynamic()==0 && target_disp <0){
260     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
261     retval = MPI_ERR_ARG;
262   } else if ((origin_count < 0 || target_count < 0) ||
263             (origin_addr==nullptr && origin_count > 0)){
264     retval = MPI_ERR_COUNT;
265   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
266             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
267     retval = MPI_ERR_TYPE;
268   } else {
269     int rank = smpi_process()->index();
270     MPI_Group group;
271     win->get_group(&group);
272     int dst_traced = group->index(target_rank);
273     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
274     TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
275
276     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
277                            target_datatype);
278
279     TRACE_smpi_ptp_out(rank);
280   }
281   smpi_bench_begin();
282   return retval;
283 }
284
285 int PMPI_Rput( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
286               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
287   int retval = 0;
288   smpi_bench_end();
289   if (win == MPI_WIN_NULL) {
290     retval = MPI_ERR_WIN;
291   } else if (target_rank == MPI_PROC_NULL) {
292     *request = MPI_REQUEST_NULL;
293     retval = MPI_SUCCESS;
294   } else if (target_rank <0){
295     retval = MPI_ERR_RANK;
296   } else if (win->dynamic()==0 && target_disp <0){
297     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
298     retval = MPI_ERR_ARG;
299   } else if ((origin_count < 0 || target_count < 0) ||
300             (origin_addr==nullptr && origin_count > 0)){
301     retval = MPI_ERR_COUNT;
302   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
303             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
304     retval = MPI_ERR_TYPE;
305   } else if(request == nullptr){
306     retval = MPI_ERR_REQUEST;
307   } else {
308     int rank = smpi_process()->index();
309     MPI_Group group;
310     win->get_group(&group);
311     int dst_traced = group->index(target_rank);
312     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
313     TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
314
315     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
316                            target_datatype, request);
317
318     TRACE_smpi_ptp_out(rank);
319   }
320   smpi_bench_begin();
321   return retval;
322 }
323
324 int PMPI_Accumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
325               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
326   int retval = 0;
327   smpi_bench_end();
328   if (win == MPI_WIN_NULL) {
329     retval = MPI_ERR_WIN;
330   } else if (target_rank == MPI_PROC_NULL) {
331     retval = MPI_SUCCESS;
332   } else if (target_rank <0){
333     retval = MPI_ERR_RANK;
334   } else if (win->dynamic()==0 && target_disp <0){
335     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
336     retval = MPI_ERR_ARG;
337   } else if ((origin_count < 0 || target_count < 0) ||
338              (origin_addr==nullptr && origin_count > 0)){
339     retval = MPI_ERR_COUNT;
340   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
341             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
342     retval = MPI_ERR_TYPE;
343   } else if (op == MPI_OP_NULL) {
344     retval = MPI_ERR_OP;
345   } else {
346     int rank = smpi_process()->index();
347     MPI_Group group;
348     win->get_group(&group);
349     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
350     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
351                                   target_datatype, op);
352
353     TRACE_smpi_ptp_out(rank);
354   }
355   smpi_bench_begin();
356   return retval;
357 }
358
359 int PMPI_Raccumulate( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
360               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
361   int retval = 0;
362   smpi_bench_end();
363   if (win == MPI_WIN_NULL) {
364     retval = MPI_ERR_WIN;
365   } else if (target_rank == MPI_PROC_NULL) {
366     *request = MPI_REQUEST_NULL;
367     retval = MPI_SUCCESS;
368   } else if (target_rank <0){
369     retval = MPI_ERR_RANK;
370   } else if (win->dynamic()==0 && target_disp <0){
371     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
372     retval = MPI_ERR_ARG;
373   } else if ((origin_count < 0 || target_count < 0) ||
374              (origin_addr==nullptr && origin_count > 0)){
375     retval = MPI_ERR_COUNT;
376   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
377             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
378     retval = MPI_ERR_TYPE;
379   } else if (op == MPI_OP_NULL) {
380     retval = MPI_ERR_OP;
381   } else if(request == nullptr){
382     retval = MPI_ERR_REQUEST;
383   } else {
384     int rank = smpi_process()->index();
385     MPI_Group group;
386     win->get_group(&group);
387     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
388
389     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
390                                   target_datatype, op, request);
391
392     TRACE_smpi_ptp_out(rank);
393   }
394   smpi_bench_begin();
395   return retval;
396 }
397
398 int PMPI_Get_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
399 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
400 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
401   int retval = 0;
402   smpi_bench_end();
403   if (win == MPI_WIN_NULL) {
404     retval = MPI_ERR_WIN;
405   } else if (target_rank == MPI_PROC_NULL) {
406     retval = MPI_SUCCESS;
407   } else if (target_rank <0){
408     retval = MPI_ERR_RANK;
409   } else if (win->dynamic()==0 && target_disp <0){
410     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
411     retval = MPI_ERR_ARG;
412   } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
413              (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
414              (result_addr==nullptr && result_count > 0)){
415     retval = MPI_ERR_COUNT;
416   } else if (((target_datatype == MPI_DATATYPE_NULL) || (result_datatype == MPI_DATATYPE_NULL)) ||
417             (((origin_datatype != MPI_DATATYPE_NULL) && (not origin_datatype->is_valid())) || (not target_datatype->is_valid()) || (not result_datatype->is_valid()))) {
418     retval = MPI_ERR_TYPE;
419   } else if (op == MPI_OP_NULL) {
420     retval = MPI_ERR_OP;
421   } else {
422     int rank = smpi_process()->index();
423     MPI_Group group;
424     win->get_group(&group);
425     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
426
427     retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
428                                   result_count, result_datatype, target_rank, target_disp,
429                                   target_count, target_datatype, op);
430
431     TRACE_smpi_ptp_out(rank);
432   }
433   smpi_bench_begin();
434   return retval;
435 }
436
437
438 int PMPI_Rget_accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
439 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
440 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
441   int retval = 0;
442   smpi_bench_end();
443   if (win == MPI_WIN_NULL) {
444     retval = MPI_ERR_WIN;
445   } else if (target_rank == MPI_PROC_NULL) {
446     *request = MPI_REQUEST_NULL;
447     retval = MPI_SUCCESS;
448   } else if (target_rank <0){
449     retval = MPI_ERR_RANK;
450   } else if (win->dynamic()==0 && target_disp <0){
451     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
452     retval = MPI_ERR_ARG;
453   } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
454              (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
455              (result_addr==nullptr && result_count > 0)){
456     retval = MPI_ERR_COUNT;
457   } else if (((target_datatype == MPI_DATATYPE_NULL) || (result_datatype == MPI_DATATYPE_NULL)) ||
458             (((origin_datatype != MPI_DATATYPE_NULL) && (not origin_datatype->is_valid())) || (not target_datatype->is_valid()) || (not result_datatype->is_valid()))) {
459     retval = MPI_ERR_TYPE;
460   } else if (op == MPI_OP_NULL) {
461     retval = MPI_ERR_OP;
462   } else if(request == nullptr){
463     retval = MPI_ERR_REQUEST;
464   } else {
465     int rank = smpi_process()->index();
466     MPI_Group group;
467     win->get_group(&group);
468     TRACE_smpi_ptp_in(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);
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, void* result_addr, MPI_Datatype datatype,
485                           int target_rank, MPI_Aint target_disp, MPI_Win win)
486 {
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 ((datatype == MPI_DATATYPE_NULL) || (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     TRACE_smpi_ptp_in(rank, __FUNCTION__, nullptr);
507
508     retval = win->compare_and_swap(origin_addr, compare_addr, result_addr, datatype, target_rank, target_disp);
509
510     TRACE_smpi_ptp_out(rank);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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 }