Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
constify MPI_Win*
[simgrid.git] / src / smpi / bindings / smpi_pmpi_win.cpp
1 /* Copyright (c) 2007-2019. 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_win.hpp"
12 #include "src/smpi/include/smpi_actor.hpp"
13
14 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
15
16 /* PMPI User level calls */
17
18 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
19   int retval = 0;
20   smpi_bench_end();
21   if (comm == MPI_COMM_NULL) {
22     retval= MPI_ERR_COMM;
23   }else if ((base == nullptr && size != 0) || disp_unit <= 0 || size < 0 ){
24     retval= MPI_ERR_OTHER;
25   }else{
26     *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
27     retval = MPI_SUCCESS;
28   }
29   smpi_bench_begin();
30   return retval;
31 }
32
33 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
34   int retval = 0;
35   smpi_bench_end();
36   if (comm == MPI_COMM_NULL) {
37     retval= MPI_ERR_COMM;
38   }else if (disp_unit <= 0 || size < 0 ){
39     retval= MPI_ERR_OTHER;
40   }else{
41     void* ptr = xbt_malloc(size);
42     if(ptr==nullptr)
43       return MPI_ERR_NO_MEM;
44     *static_cast<void**>(base) = ptr;
45     *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
46     retval = MPI_SUCCESS;
47   }
48   smpi_bench_begin();
49   return retval;
50 }
51
52 int PMPI_Win_allocate_shared( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
53   int retval = 0;
54   smpi_bench_end();
55   if (comm == MPI_COMM_NULL) {
56     retval= MPI_ERR_COMM;
57   }else if (disp_unit <= 0 || size < 0 ){
58     retval= MPI_ERR_OTHER;
59   }else{
60     void* ptr = nullptr;
61     int rank = comm->rank();
62     if(rank==0){
63        ptr = xbt_malloc(size*comm->size());
64        if(ptr==nullptr)
65          return MPI_ERR_NO_MEM;
66     }
67     
68     simgrid::smpi::Colls::bcast(&ptr, sizeof(void*), MPI_BYTE, 0, comm);
69     simgrid::smpi::Colls::barrier(comm);
70     
71     *static_cast<void**>(base) = (char*)ptr+rank*size;
72     *win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,rank==0);
73     retval = MPI_SUCCESS;
74   }
75   smpi_bench_begin();
76   return retval;
77 }
78
79 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
80   int retval = 0;
81   smpi_bench_end();
82   if (comm == MPI_COMM_NULL) {
83     retval= MPI_ERR_COMM;
84   }else{
85     *win = new simgrid::smpi::Win(info, comm);
86     retval = MPI_SUCCESS;
87   }
88   smpi_bench_begin();
89   return retval;
90 }
91
92 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
93   int retval = 0;
94   smpi_bench_end();
95   if(win == MPI_WIN_NULL){
96     retval = MPI_ERR_WIN;
97   } else if ((base == nullptr && size != 0) || size < 0 ){
98     retval= MPI_ERR_OTHER;
99   }else{
100     retval = win->attach(base, size);
101   }
102   smpi_bench_begin();
103   return retval;
104 }
105
106 int PMPI_Win_detach(MPI_Win win, const void* base)
107 {
108   int retval = 0;
109   smpi_bench_end();
110   if(win == MPI_WIN_NULL){
111     retval = MPI_ERR_WIN;
112   } else if (base == nullptr){
113     retval= MPI_ERR_OTHER;
114   }else{
115     retval = win->detach(base);
116   }
117   smpi_bench_begin();
118   return retval;
119 }
120
121
122 int PMPI_Win_free( MPI_Win* win){
123   int retval = 0;
124   smpi_bench_end();
125   if (win == nullptr || *win == MPI_WIN_NULL) {
126     retval = MPI_ERR_WIN;
127   }else{
128     delete *win;
129     retval=MPI_SUCCESS;
130   }
131   smpi_bench_begin();
132   return retval;
133 }
134
135 int PMPI_Win_set_name(MPI_Win  win, const char * name)
136 {
137   if (win == MPI_WIN_NULL)  {
138     return MPI_ERR_TYPE;
139   } else if (name == nullptr)  {
140     return MPI_ERR_ARG;
141   } else {
142     win->set_name(name);
143     return MPI_SUCCESS;
144   }
145 }
146
147 int PMPI_Win_get_name(MPI_Win  win, char * name, int* len)
148 {
149   if (win == MPI_WIN_NULL)  {
150     return MPI_ERR_WIN;
151   } else if (name == nullptr)  {
152     return MPI_ERR_ARG;
153   } else {
154     win->get_name(name, len);
155     return MPI_SUCCESS;
156   }
157 }
158
159 int PMPI_Win_get_info(MPI_Win  win, MPI_Info* info)
160 {
161   if (win == MPI_WIN_NULL)  {
162     return MPI_ERR_WIN;
163   } else {
164     *info = win->info();
165     return MPI_SUCCESS;
166   }
167 }
168
169 int PMPI_Win_set_info(MPI_Win  win, MPI_Info info)
170 {
171   if (win == MPI_WIN_NULL)  {
172     return MPI_ERR_TYPE;
173   } else {
174     win->set_info(info);
175     return MPI_SUCCESS;
176   }
177 }
178
179 int PMPI_Win_get_group(MPI_Win  win, MPI_Group * group){
180   if (win == MPI_WIN_NULL)  {
181     return MPI_ERR_WIN;
182   }else {
183     win->get_group(group);
184     (*group)->ref();
185     return MPI_SUCCESS;
186   }
187 }
188
189 int PMPI_Win_fence( int assert,  MPI_Win win){
190   int retval = 0;
191   smpi_bench_end();
192   if (win == MPI_WIN_NULL) {
193     retval = MPI_ERR_WIN;
194   } else {
195     int my_proc_id = simgrid::s4u::this_actor::get_pid();
196     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_fence"));
197     retval = win->fence(assert);
198     TRACE_smpi_comm_out(my_proc_id);
199   }
200   smpi_bench_begin();
201   return retval;
202 }
203
204 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
205               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
206   int retval = 0;
207   smpi_bench_end();
208   if (win == MPI_WIN_NULL) {
209     retval = MPI_ERR_WIN;
210   } else if (target_rank == MPI_PROC_NULL) {
211     retval = MPI_SUCCESS;
212   } else if (target_rank <0){
213     retval = MPI_ERR_RANK;
214   } else if (win->dynamic()==0 && target_disp <0){
215     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
216     retval = MPI_ERR_ARG;
217   } else if ((origin_count < 0 || target_count < 0) ||
218              (origin_addr==nullptr && origin_count > 0)){
219     retval = MPI_ERR_COUNT;
220   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
221             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
222     retval = MPI_ERR_TYPE;
223   } else {
224     int my_proc_id = simgrid::s4u::this_actor::get_pid();
225     MPI_Group group;
226     win->get_group(&group);
227     TRACE_smpi_comm_in(my_proc_id, __func__,
228                        new simgrid::instr::Pt2PtTIData("Get", target_rank, origin_datatype->is_replayable()
229                                                                                ? origin_count
230                                                                                : origin_count * origin_datatype->size(),
231                                                        simgrid::smpi::Datatype::encode(origin_datatype)));
232
233     retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
234                            target_datatype);
235
236     TRACE_smpi_comm_out(my_proc_id);
237   }
238   smpi_bench_begin();
239   return retval;
240 }
241
242 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
243               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
244   int retval = 0;
245   smpi_bench_end();
246   if (win == MPI_WIN_NULL) {
247     retval = MPI_ERR_WIN;
248   } else if (target_rank == MPI_PROC_NULL) {
249     *request = MPI_REQUEST_NULL;
250     retval = MPI_SUCCESS;
251   } else if (target_rank <0){
252     retval = MPI_ERR_RANK;
253   } else if (win->dynamic()==0 && target_disp <0){
254     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
255     retval = MPI_ERR_ARG;
256   } else if ((origin_count < 0 || target_count < 0) ||
257              (origin_addr==nullptr && origin_count > 0)){
258     retval = MPI_ERR_COUNT;
259   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
260             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
261     retval = MPI_ERR_TYPE;
262   } else if(request == nullptr){
263     retval = MPI_ERR_REQUEST;
264   } else {
265     int my_proc_id = simgrid::s4u::this_actor::get_pid();
266     MPI_Group group;
267     win->get_group(&group);
268     TRACE_smpi_comm_in(my_proc_id, __func__,
269                        new simgrid::instr::Pt2PtTIData(
270                            "Rget", target_rank,
271                            origin_datatype->is_replayable() ? origin_count : origin_count * origin_datatype->size(),
272                            simgrid::smpi::Datatype::encode(origin_datatype)));
273
274     retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
275                            target_datatype, request);
276
277     TRACE_smpi_comm_out(my_proc_id);
278   }
279   smpi_bench_begin();
280   return retval;
281 }
282
283 int PMPI_Put(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
284               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
285   int retval = 0;
286   smpi_bench_end();
287   if (win == MPI_WIN_NULL) {
288     retval = MPI_ERR_WIN;
289   } else if (target_rank == MPI_PROC_NULL) {
290     retval = MPI_SUCCESS;
291   } else if (target_rank <0){
292     retval = MPI_ERR_RANK;
293   } else if (win->dynamic()==0 && target_disp <0){
294     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
295     retval = MPI_ERR_ARG;
296   } else if ((origin_count < 0 || target_count < 0) ||
297             (origin_addr==nullptr && origin_count > 0)){
298     retval = MPI_ERR_COUNT;
299   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
300             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
301     retval = MPI_ERR_TYPE;
302   } else {
303     int my_proc_id = simgrid::s4u::this_actor::get_pid();
304     MPI_Group group;
305     win->get_group(&group);
306     int dst_traced = group->actor(target_rank)->get_pid();
307     TRACE_smpi_comm_in(my_proc_id, __func__,
308                        new simgrid::instr::Pt2PtTIData("Put", target_rank, origin_datatype->is_replayable()
309                                                                                ? origin_count
310                                                                                : origin_count * origin_datatype->size(),
311                                                        simgrid::smpi::Datatype::encode(origin_datatype)));
312     TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, SMPI_RMA_TAG, origin_count * origin_datatype->size());
313
314     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
315                            target_datatype);
316
317     TRACE_smpi_comm_out(my_proc_id);
318   }
319   smpi_bench_begin();
320   return retval;
321 }
322
323 int PMPI_Rput(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
324               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
325   int retval = 0;
326   smpi_bench_end();
327   if (win == MPI_WIN_NULL) {
328     retval = MPI_ERR_WIN;
329   } else if (target_rank == MPI_PROC_NULL) {
330     *request = MPI_REQUEST_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(request == nullptr){
344     retval = MPI_ERR_REQUEST;
345   } else {
346     int my_proc_id = simgrid::s4u::this_actor::get_pid();
347     MPI_Group group;
348     win->get_group(&group);
349     int dst_traced = group->actor(target_rank)->get_pid();
350     TRACE_smpi_comm_in(my_proc_id, __func__,
351                        new simgrid::instr::Pt2PtTIData(
352                            "Rput", target_rank,
353                            origin_datatype->is_replayable() ? origin_count : origin_count * origin_datatype->size(),
354                            simgrid::smpi::Datatype::encode(origin_datatype)));
355     TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, SMPI_RMA_TAG, origin_count * origin_datatype->size());
356
357     retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
358                            target_datatype, request);
359
360     TRACE_smpi_comm_out(my_proc_id);
361   }
362   smpi_bench_begin();
363   return retval;
364 }
365
366 int PMPI_Accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
367               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
368   int retval = 0;
369   smpi_bench_end();
370   if (win == MPI_WIN_NULL) {
371     retval = MPI_ERR_WIN;
372   } else if (target_rank == MPI_PROC_NULL) {
373     retval = MPI_SUCCESS;
374   } else if (target_rank <0){
375     retval = MPI_ERR_RANK;
376   } else if (win->dynamic()==0 && target_disp <0){
377     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
378     retval = MPI_ERR_ARG;
379   } else if ((origin_count < 0 || target_count < 0) ||
380              (origin_addr==nullptr && origin_count > 0)){
381     retval = MPI_ERR_COUNT;
382   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
383             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
384     retval = MPI_ERR_TYPE;
385   } else if (op == MPI_OP_NULL) {
386     retval = MPI_ERR_OP;
387   } else {
388     int my_proc_id = simgrid::s4u::this_actor::get_pid();
389     MPI_Group group;
390     win->get_group(&group);
391     TRACE_smpi_comm_in(my_proc_id, __func__,
392                        new simgrid::instr::Pt2PtTIData(
393                            "Accumulate", target_rank,
394                            origin_datatype->is_replayable() ? origin_count : origin_count * origin_datatype->size(),
395                            simgrid::smpi::Datatype::encode(origin_datatype)));
396     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
397                                   target_datatype, op);
398
399     TRACE_smpi_comm_out(my_proc_id);
400   }
401   smpi_bench_begin();
402   return retval;
403 }
404
405 int PMPI_Raccumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
406               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
407   int retval = 0;
408   smpi_bench_end();
409   if (win == MPI_WIN_NULL) {
410     retval = MPI_ERR_WIN;
411   } else if (target_rank == MPI_PROC_NULL) {
412     *request = MPI_REQUEST_NULL;
413     retval = MPI_SUCCESS;
414   } else if (target_rank <0){
415     retval = MPI_ERR_RANK;
416   } else if (win->dynamic()==0 && target_disp <0){
417     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
418     retval = MPI_ERR_ARG;
419   } else if ((origin_count < 0 || target_count < 0) ||
420              (origin_addr==nullptr && origin_count > 0)){
421     retval = MPI_ERR_COUNT;
422   } else if (((origin_datatype == MPI_DATATYPE_NULL) || (target_datatype == MPI_DATATYPE_NULL)) ||
423             ((not origin_datatype->is_valid()) || (not target_datatype->is_valid()))) {
424     retval = MPI_ERR_TYPE;
425   } else if (op == MPI_OP_NULL) {
426     retval = MPI_ERR_OP;
427   } else if(request == nullptr){
428     retval = MPI_ERR_REQUEST;
429   } else {
430     int my_proc_id = simgrid::s4u::this_actor::get_pid();
431     MPI_Group group;
432     win->get_group(&group);
433     TRACE_smpi_comm_in(my_proc_id, __func__,
434                        new simgrid::instr::Pt2PtTIData(
435                            "Raccumulate", target_rank,
436                            origin_datatype->is_replayable() ? origin_count : origin_count * origin_datatype->size(),
437                            simgrid::smpi::Datatype::encode(origin_datatype)));
438
439     retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
440                                   target_datatype, op, request);
441
442     TRACE_smpi_comm_out(my_proc_id);
443   }
444   smpi_bench_begin();
445   return retval;
446 }
447
448 int PMPI_Get_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
449 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
450 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
451   int retval = 0;
452   smpi_bench_end();
453   if (win == MPI_WIN_NULL) {
454     retval = MPI_ERR_WIN;
455   } else if (target_rank == MPI_PROC_NULL) {
456     retval = MPI_SUCCESS;
457   } else if (target_rank <0){
458     retval = MPI_ERR_RANK;
459   } else if (win->dynamic()==0 && target_disp <0){
460     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
461     retval = MPI_ERR_ARG;
462   } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
463              (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
464              (result_addr==nullptr && result_count > 0)){
465     retval = MPI_ERR_COUNT;
466   } else if (((target_datatype == MPI_DATATYPE_NULL) || (result_datatype == MPI_DATATYPE_NULL)) ||
467             (((origin_datatype != MPI_DATATYPE_NULL) && (not origin_datatype->is_valid())) || (not target_datatype->is_valid()) || (not result_datatype->is_valid()))) {
468     retval = MPI_ERR_TYPE;
469   } else if (op == MPI_OP_NULL) {
470     retval = MPI_ERR_OP;
471   } else {
472     int my_proc_id = simgrid::s4u::this_actor::get_pid();
473     MPI_Group group;
474     win->get_group(&group);
475     TRACE_smpi_comm_in(my_proc_id, __func__,
476                        new simgrid::instr::Pt2PtTIData(
477                            "Get_accumulate", target_rank,
478                            target_datatype->is_replayable() ? target_count : target_count * target_datatype->size(),
479                            simgrid::smpi::Datatype::encode(target_datatype)));
480
481     retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
482                                   result_count, result_datatype, target_rank, target_disp,
483                                   target_count, target_datatype, op);
484
485     TRACE_smpi_comm_out(my_proc_id);
486   }
487   smpi_bench_begin();
488   return retval;
489 }
490
491
492 int PMPI_Rget_accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, void *result_addr,
493 int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp, int target_count,
494 MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
495   int retval = 0;
496   smpi_bench_end();
497   if (win == MPI_WIN_NULL) {
498     retval = MPI_ERR_WIN;
499   } else if (target_rank == MPI_PROC_NULL) {
500     *request = MPI_REQUEST_NULL;
501     retval = MPI_SUCCESS;
502   } else if (target_rank <0){
503     retval = MPI_ERR_RANK;
504   } else if (win->dynamic()==0 && target_disp <0){
505     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
506     retval = MPI_ERR_ARG;
507   } else if ((origin_count < 0 || target_count < 0 || result_count <0) ||
508              (origin_addr==nullptr && origin_count > 0 && op != MPI_NO_OP) ||
509              (result_addr==nullptr && result_count > 0)){
510     retval = MPI_ERR_COUNT;
511   } else if (((target_datatype == MPI_DATATYPE_NULL) || (result_datatype == MPI_DATATYPE_NULL)) ||
512             (((origin_datatype != MPI_DATATYPE_NULL) && (not origin_datatype->is_valid())) || (not target_datatype->is_valid()) || (not result_datatype->is_valid()))) {
513     retval = MPI_ERR_TYPE;
514   } else if (op == MPI_OP_NULL) {
515     retval = MPI_ERR_OP;
516   } else if(request == nullptr){
517     retval = MPI_ERR_REQUEST;
518   } else {
519     int my_proc_id = simgrid::s4u::this_actor::get_pid();
520     MPI_Group group;
521     win->get_group(&group);
522     TRACE_smpi_comm_in(my_proc_id, __func__,
523                        new simgrid::instr::Pt2PtTIData(
524                            "Rget_accumulate", target_rank,
525                            target_datatype->is_replayable() ? target_count : target_count * target_datatype->size(),
526                            simgrid::smpi::Datatype::encode(target_datatype)));
527
528     retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
529                                   result_count, result_datatype, target_rank, target_disp,
530                                   target_count, target_datatype, op, request);
531
532     TRACE_smpi_comm_out(my_proc_id);
533   }
534   smpi_bench_begin();
535   return retval;
536 }
537
538 int PMPI_Fetch_and_op(const void *origin_addr, void *result_addr, MPI_Datatype dtype, int target_rank, MPI_Aint target_disp, MPI_Op op, MPI_Win win){
539   return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
540 }
541
542 int PMPI_Compare_and_swap(const void* origin_addr, void* compare_addr, void* result_addr, MPI_Datatype datatype,
543                           int target_rank, MPI_Aint target_disp, MPI_Win win)
544 {
545   int retval = 0;
546   smpi_bench_end();
547   if (win == MPI_WIN_NULL) {
548     retval = MPI_ERR_WIN;
549   } else if (target_rank == MPI_PROC_NULL) {
550     retval = MPI_SUCCESS;
551   } else if (target_rank <0){
552     retval = MPI_ERR_RANK;
553   } else if (win->dynamic()==0 && target_disp <0){
554     //in case of dynamic window, target_disp can be mistakenly seen as negative, as it is an address
555     retval = MPI_ERR_ARG;
556   } else if (origin_addr==nullptr || result_addr==nullptr || compare_addr==nullptr){
557     retval = MPI_ERR_COUNT;
558   } else if ((datatype == MPI_DATATYPE_NULL) || (not datatype->is_valid())) {
559     retval = MPI_ERR_TYPE;
560   } else {
561     int my_proc_id = simgrid::s4u::this_actor::get_pid();
562     MPI_Group group;
563     win->get_group(&group);
564     TRACE_smpi_comm_in(my_proc_id, __func__,
565                        new simgrid::instr::Pt2PtTIData("Compare_and_swap", target_rank,
566                                                        datatype->is_replayable() ? 1 : datatype->size(),
567                                                        simgrid::smpi::Datatype::encode(datatype)));
568
569     retval = win->compare_and_swap(origin_addr, compare_addr, result_addr, datatype, target_rank, target_disp);
570
571     TRACE_smpi_comm_out(my_proc_id);
572   }
573   smpi_bench_begin();
574   return retval;
575 }
576
577 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
578   int retval = 0;
579   smpi_bench_end();
580   if (win == MPI_WIN_NULL) {
581     retval = MPI_ERR_WIN;
582   } else if (group==MPI_GROUP_NULL){
583     retval = MPI_ERR_GROUP;
584   } else {
585     int my_proc_id = simgrid::s4u::this_actor::get_pid();
586     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_post"));
587     retval = win->post(group,assert);
588     TRACE_smpi_comm_out(my_proc_id);
589   }
590   smpi_bench_begin();
591   return retval;
592 }
593
594 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
595   int retval = 0;
596   smpi_bench_end();
597   if (win == MPI_WIN_NULL) {
598     retval = MPI_ERR_WIN;
599   } else if (group==MPI_GROUP_NULL){
600     retval = MPI_ERR_GROUP;
601   } else {
602     int my_proc_id = simgrid::s4u::this_actor::get_pid();
603     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_start"));
604     retval = win->start(group,assert);
605     TRACE_smpi_comm_out(my_proc_id);
606   }
607   smpi_bench_begin();
608   return retval;
609 }
610
611 int PMPI_Win_complete(MPI_Win win){
612   int retval = 0;
613   smpi_bench_end();
614   if (win == MPI_WIN_NULL) {
615     retval = MPI_ERR_WIN;
616   } else {
617     int my_proc_id = simgrid::s4u::this_actor::get_pid();
618     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_complete"));
619
620     retval = win->complete();
621
622     TRACE_smpi_comm_out(my_proc_id);
623   }
624   smpi_bench_begin();
625   return retval;
626 }
627
628 int PMPI_Win_wait(MPI_Win win){
629   int retval = 0;
630   smpi_bench_end();
631   if (win == MPI_WIN_NULL) {
632     retval = MPI_ERR_WIN;
633   } else {
634     int my_proc_id = simgrid::s4u::this_actor::get_pid();
635     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_wait"));
636
637     retval = win->wait();
638
639     TRACE_smpi_comm_out(my_proc_id);
640   }
641   smpi_bench_begin();
642   return retval;
643 }
644
645 int PMPI_Win_lock(int lock_type, int rank, int assert, 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 (lock_type != MPI_LOCK_EXCLUSIVE &&
651              lock_type != MPI_LOCK_SHARED) {
652     retval = MPI_ERR_LOCKTYPE;
653   } else if (rank == MPI_PROC_NULL){
654     retval = MPI_SUCCESS;
655   } else {
656     int my_proc_id = simgrid::s4u::this_actor::get_pid();
657     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_lock"));
658     retval = win->lock(lock_type,rank,assert);
659     TRACE_smpi_comm_out(my_proc_id);
660   }
661   smpi_bench_begin();
662   return retval;
663 }
664
665 int PMPI_Win_unlock(int rank, MPI_Win win){
666   int retval = 0;
667   smpi_bench_end();
668   if (win == MPI_WIN_NULL) {
669     retval = MPI_ERR_WIN;
670   } else if (rank == MPI_PROC_NULL){
671     retval = MPI_SUCCESS;
672   } else {
673     int my_proc_id = simgrid::s4u::this_actor::get_pid();
674     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_unlock"));
675     retval = win->unlock(rank);
676     TRACE_smpi_comm_out(my_proc_id);
677   }
678   smpi_bench_begin();
679   return retval;
680 }
681
682 int PMPI_Win_lock_all(int assert, MPI_Win win){
683   int retval = 0;
684   smpi_bench_end();
685   if (win == MPI_WIN_NULL) {
686     retval = MPI_ERR_WIN;
687   } else {
688     int my_proc_id = simgrid::s4u::this_actor::get_pid();
689     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_lock_all"));
690     retval = win->lock_all(assert);
691     TRACE_smpi_comm_out(my_proc_id);
692   }
693   smpi_bench_begin();
694   return retval;
695 }
696
697 int PMPI_Win_unlock_all(MPI_Win win){
698   int retval = 0;
699   smpi_bench_end();
700   if (win == MPI_WIN_NULL) {
701     retval = MPI_ERR_WIN;
702   } else {
703     int my_proc_id = simgrid::s4u::this_actor::get_pid();
704     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_unlock_all"));
705     retval = win->unlock_all();
706     TRACE_smpi_comm_out(my_proc_id);
707   }
708   smpi_bench_begin();
709   return retval;
710 }
711
712 int PMPI_Win_flush(int rank, MPI_Win win){
713   int retval = 0;
714   smpi_bench_end();
715   if (win == MPI_WIN_NULL) {
716     retval = MPI_ERR_WIN;
717   } else if (rank == MPI_PROC_NULL){
718     retval = MPI_SUCCESS;
719   } else {
720     int my_proc_id = simgrid::s4u::this_actor::get_pid();
721     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush"));
722     retval = win->flush(rank);
723     TRACE_smpi_comm_out(my_proc_id);
724   }
725   smpi_bench_begin();
726   return retval;
727 }
728
729 int PMPI_Win_flush_local(int rank, MPI_Win win){
730   int retval = 0;
731   smpi_bench_end();
732   if (win == MPI_WIN_NULL) {
733     retval = MPI_ERR_WIN;
734   } else if (rank == MPI_PROC_NULL){
735     retval = MPI_SUCCESS;
736   } else {
737     int my_proc_id = simgrid::s4u::this_actor::get_pid();
738     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush_local"));
739     retval = win->flush_local(rank);
740     TRACE_smpi_comm_out(my_proc_id);
741   }
742   smpi_bench_begin();
743   return retval;
744 }
745
746 int PMPI_Win_flush_all(MPI_Win win){
747   int retval = 0;
748   smpi_bench_end();
749   if (win == MPI_WIN_NULL) {
750     retval = MPI_ERR_WIN;
751   } else {
752     int my_proc_id = simgrid::s4u::this_actor::get_pid();
753     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush_all"));
754     retval = win->flush_all();
755     TRACE_smpi_comm_out(my_proc_id);
756   }
757   smpi_bench_begin();
758   return retval;
759 }
760
761 int PMPI_Win_flush_local_all(MPI_Win win){
762   int retval = 0;
763   smpi_bench_end();
764   if (win == MPI_WIN_NULL) {
765     retval = MPI_ERR_WIN;
766   } else {
767     int my_proc_id = simgrid::s4u::this_actor::get_pid();
768     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush_local_all"));
769     retval = win->flush_local_all();
770     TRACE_smpi_comm_out(my_proc_id);
771   }
772   smpi_bench_begin();
773   return retval;
774 }
775
776 int PMPI_Win_shared_query (MPI_Win win, int rank, MPI_Aint* size, int* disp_unit, void* baseptr)
777 {
778   if (win==MPI_WIN_NULL)
779     return MPI_ERR_TYPE;
780   else
781     return win->shared_query(rank, size, disp_unit, baseptr);
782 }
783
784 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
785 {
786   static MPI_Aint size;
787   static MPI_Aint disp_unit;
788   if (win==MPI_WIN_NULL)
789     return MPI_ERR_TYPE;
790   else{
791   switch (keyval) {
792     case MPI_WIN_BASE :
793       *static_cast<void**>(attribute_val)  = win->base();
794       *flag = 1;
795       return MPI_SUCCESS;
796     case MPI_WIN_SIZE :
797       size = win->size();
798       *static_cast<MPI_Aint**>(attribute_val)  = &size;
799       *flag = 1;
800       return MPI_SUCCESS;
801     case MPI_WIN_DISP_UNIT :
802       disp_unit=win->disp_unit();
803       *static_cast<MPI_Aint**>(attribute_val)  = &disp_unit;
804       *flag = 1;
805       return MPI_SUCCESS;
806     default:
807       return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
808   }
809 }
810
811 }
812
813 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
814 {
815   if (win==MPI_WIN_NULL)
816     return MPI_ERR_TYPE;
817   else
818     return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
819 }
820
821 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
822 {
823   if (win==MPI_WIN_NULL)
824     return MPI_ERR_TYPE;
825   else
826     return win->attr_delete<simgrid::smpi::Win>(type_keyval);
827 }
828
829 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
830                             void* extra_state)
831 {
832   smpi_copy_fn _copy_fn={nullptr, nullptr,copy_fn,nullptr, nullptr,nullptr};
833   smpi_delete_fn _delete_fn={nullptr, nullptr,delete_fn,nullptr, nullptr,nullptr};
834   return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
835 }
836
837 int PMPI_Win_free_keyval(int* keyval) {
838   return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
839 }
840
841 MPI_Win PMPI_Win_f2c(MPI_Fint win){
842   return static_cast<MPI_Win>(simgrid::smpi::Win::f2c(win));
843 }
844
845 MPI_Fint PMPI_Win_c2f(MPI_Win win){
846   return win->c2f();
847 }