Logo AND Algorithmique Numérique Distribuée

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