Logo AND Algorithmique Numérique Distribuée

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