Logo AND Algorithmique Numérique Distribuée

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