Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
kill is_replayable() for datatypes.
[simgrid.git] / src / smpi / bindings / smpi_pmpi_win.cpp
1 /* Copyright (c) 2007-2021. 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 #define CHECK_RMA\
17   CHECK_COUNT(2, origin_count)\
18   CHECK_TYPE(3, origin_datatype)\
19   CHECK_BUFFER(1, origin_addr, origin_count, origin_datatype)\
20   CHECK_PROC_RMA(4, target_rank, win)\
21   CHECK_COUNT(6, target_count)\
22   CHECK_TYPE(7, target_datatype)
23
24 #define CHECK_TARGET_DISP(num)                                                                                         \
25   if (not win->dynamic())                                                                                              \
26     CHECK_NEGATIVE((num), MPI_ERR_RMA_RANGE, target_disp)
27
28 /* PMPI User level calls */
29
30 int PMPI_Win_create( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, MPI_Win *win){
31   int retval = 0;
32   CHECK_COMM(5)
33   CHECK_NEGATIVE(2, MPI_ERR_OTHER, size)
34   CHECK_NEGATIVE(3, MPI_ERR_OTHER, disp_unit)
35   const SmpiBenchGuard suspend_bench;
36   if (base == nullptr && size != 0){
37     retval= MPI_ERR_OTHER;
38   }else{
39     *win = new simgrid::smpi::Win( base, size, disp_unit, info, comm);
40     retval = MPI_SUCCESS;
41   }
42   return retval;
43 }
44
45 int PMPI_Win_allocate( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
46   CHECK_COMM(5)
47   CHECK_NEGATIVE(2, MPI_ERR_OTHER, size)
48   CHECK_NEGATIVE(3, MPI_ERR_OTHER, disp_unit)
49   void* ptr = xbt_malloc(size);
50   const SmpiBenchGuard suspend_bench;
51   *static_cast<void**>(base) = ptr;
52   *win                       = new simgrid::smpi::Win(ptr, size, disp_unit, info, comm, true);
53   return MPI_SUCCESS;
54 }
55
56 int PMPI_Win_allocate_shared( MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *base, MPI_Win *win){
57   CHECK_COMM(5)
58   CHECK_NEGATIVE(2, MPI_ERR_OTHER, size)
59   CHECK_NEGATIVE(3, MPI_ERR_OTHER, disp_unit)
60   void* ptr = nullptr;
61   int rank = comm->rank();
62   if(rank==0){
63      ptr = xbt_malloc(size*comm->size());
64   }
65   const SmpiBenchGuard suspend_bench;
66   simgrid::smpi::colls::bcast(&ptr, sizeof(void*), MPI_BYTE, 0, comm);
67   simgrid::smpi::colls::barrier(comm);
68   *static_cast<void**>(base) = (char*)ptr+rank*size;
69   *win                       = new simgrid::smpi::Win(ptr, size, disp_unit, info, comm, rank == 0);
70   return MPI_SUCCESS;
71 }
72
73 int PMPI_Win_create_dynamic( MPI_Info info, MPI_Comm comm, MPI_Win *win){
74   CHECK_COMM(2)
75   const SmpiBenchGuard suspend_bench;
76   *win = new simgrid::smpi::Win(info, comm);
77   return MPI_SUCCESS;
78 }
79
80 int PMPI_Win_attach(MPI_Win win, void *base, MPI_Aint size){
81   CHECK_WIN(1, win)
82   CHECK_NEGATIVE(3, MPI_ERR_OTHER, size)
83   if (base == nullptr && size != 0)
84     return MPI_ERR_OTHER;
85   const SmpiBenchGuard suspend_bench;
86   int retval = win->attach(base, size);
87   return retval;
88 }
89
90 int PMPI_Win_detach(MPI_Win win, const void* base)
91 {
92   CHECK_WIN(1, win)
93   CHECK_NULL(2, MPI_ERR_OTHER, base)
94   const SmpiBenchGuard suspend_bench;
95   int retval = win->detach(base);
96   return retval;
97 }
98
99 int PMPI_Win_free( MPI_Win* win){
100   CHECK_NULL(1, MPI_ERR_WIN, win)
101   CHECK_WIN(1, (*win))
102   if (_smpi_cfg_pedantic && (*win)->opened() == 1){//only check in pedantic mode, as it's not clear this is illegal
103     XBT_WARN("Attempt to destroy a MPI_Win too early -missing MPI_Win_fence ?");
104     return MPI_ERR_WIN;
105   }
106   const SmpiBenchGuard suspend_bench;
107   delete *win;
108   return MPI_SUCCESS;
109 }
110
111 int PMPI_Win_set_name(MPI_Win  win, const char * name)
112 {
113   CHECK_WIN(1, win)
114   CHECK_NULL(2, MPI_ERR_ARG, name)
115   win->set_name(name);
116   return MPI_SUCCESS;
117 }
118
119 int PMPI_Win_get_name(MPI_Win  win, char * name, int* len)
120 {
121   CHECK_WIN(1, win)
122   CHECK_NULL(2, MPI_ERR_ARG, name)
123   win->get_name(name, len);
124   return MPI_SUCCESS;
125 }
126
127 int PMPI_Win_get_info(MPI_Win  win, MPI_Info* info)
128 {
129   CHECK_WIN(1, win)
130   CHECK_NULL(2, MPI_ERR_ARG, info)
131   *info = new simgrid::smpi::Info(win->info());
132   return MPI_SUCCESS;
133 }
134
135 int PMPI_Win_set_info(MPI_Win  win, MPI_Info info)
136 {
137   CHECK_WIN(1, win)
138   win->set_info(info);
139   return MPI_SUCCESS;
140 }
141
142 int PMPI_Win_get_group(MPI_Win  win, MPI_Group * group){
143   CHECK_WIN(1, win)
144   win->get_group(group);
145   if (*group != MPI_COMM_WORLD->group() && *group != MPI_GROUP_NULL && *group != MPI_GROUP_EMPTY)
146     (*group)->ref();
147   return MPI_SUCCESS;
148 }
149
150 int PMPI_Win_fence( int assert,  MPI_Win win){
151   CHECK_WIN(2, win)
152   const SmpiBenchGuard suspend_bench;
153   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
154   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_fence"));
155   int retval = win->fence(assert);
156   TRACE_smpi_comm_out(my_proc_id);
157   return retval;
158 }
159
160 int PMPI_Get( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
161               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
162   CHECK_WIN(8, win)
163   CHECK_RMA
164   CHECK_TARGET_DISP(5)
165
166   int retval = 0;
167   const SmpiBenchGuard suspend_bench;
168
169   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
170   MPI_Group group;
171   win->get_group(&group);
172   TRACE_smpi_comm_in(my_proc_id, __func__,
173                      new simgrid::instr::Pt2PtTIData("Get", target_rank, origin_count,
174                                                      simgrid::smpi::Datatype::encode(origin_datatype)));
175    retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
176                          target_datatype);
177   TRACE_smpi_comm_out(my_proc_id);
178  
179   return retval;
180 }
181
182 int PMPI_Rget( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
183               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
184   if(target_rank==MPI_PROC_NULL)
185     *request = MPI_REQUEST_NULL;
186   CHECK_WIN(8, win)
187   CHECK_RMA
188   CHECK_TARGET_DISP(5)
189   CHECK_NULL(9, MPI_ERR_ARG, request)
190
191   int retval = 0;
192   const SmpiBenchGuard suspend_bench;
193
194   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
195   MPI_Group group;
196   win->get_group(&group);
197   TRACE_smpi_comm_in(my_proc_id, __func__,
198                      new simgrid::instr::Pt2PtTIData(
199                          "Rget", target_rank, origin_count,
200                          simgrid::smpi::Datatype::encode(origin_datatype)));
201
202   retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
203                          target_datatype, request);
204
205   TRACE_smpi_comm_out(my_proc_id);
206
207   return retval;
208 }
209
210 int PMPI_Put(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
211               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win){
212   CHECK_WIN(8, win)
213   CHECK_RMA
214   CHECK_TARGET_DISP(5)
215
216   int retval = 0;
217   const SmpiBenchGuard suspend_bench;
218
219   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
220   MPI_Group group;
221   win->get_group(&group);
222   aid_t dst_traced = group->actor(target_rank);
223   TRACE_smpi_comm_in(my_proc_id, __func__,
224                      new simgrid::instr::Pt2PtTIData("Put", target_rank, origin_count,
225                                                      simgrid::smpi::Datatype::encode(origin_datatype)));
226   TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, SMPI_RMA_TAG, origin_count * origin_datatype->size());
227
228   retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
229                          target_datatype);
230
231   TRACE_smpi_comm_out(my_proc_id);
232
233   return retval;
234 }
235
236 int PMPI_Rput(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
237               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request){
238   if(target_rank==MPI_PROC_NULL)
239     *request = MPI_REQUEST_NULL;
240   CHECK_WIN(8, win)
241   CHECK_RMA
242   CHECK_TARGET_DISP(5)
243   CHECK_NULL(9, MPI_ERR_ARG, request)
244   int retval = 0;
245   const SmpiBenchGuard suspend_bench;
246
247   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
248   MPI_Group group;
249   win->get_group(&group);
250   aid_t dst_traced = group->actor(target_rank);
251   TRACE_smpi_comm_in(my_proc_id, __func__,
252                      new simgrid::instr::Pt2PtTIData(
253                          "Rput", target_rank, origin_count,
254                          simgrid::smpi::Datatype::encode(origin_datatype)));
255   TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, SMPI_RMA_TAG, origin_count * origin_datatype->size());
256
257   retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
258                          target_datatype, request);
259
260   TRACE_smpi_comm_out(my_proc_id);
261
262   return retval;
263 }
264
265 int PMPI_Accumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
266               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win){
267   CHECK_WIN(9, win)
268   CHECK_RMA
269   CHECK_MPI_NULL(8, MPI_OP_NULL, MPI_ERR_OP, op)
270   CHECK_TARGET_DISP(5)
271
272   int retval = 0;
273
274   const SmpiBenchGuard suspend_bench;
275   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
276   MPI_Group group;
277   win->get_group(&group);
278   TRACE_smpi_comm_in(my_proc_id, __func__,
279                      new simgrid::instr::Pt2PtTIData(
280                          "Accumulate", target_rank, origin_count,
281                          simgrid::smpi::Datatype::encode(origin_datatype)));
282   retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
283                                 target_datatype, op);
284
285   TRACE_smpi_comm_out(my_proc_id);
286
287   return retval;
288 }
289
290 int PMPI_Raccumulate(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
291               MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request){
292   if(target_rank==MPI_PROC_NULL)
293     *request = MPI_REQUEST_NULL;
294   CHECK_WIN(9, win)
295   CHECK_RMA
296   CHECK_MPI_NULL(8, MPI_OP_NULL, MPI_ERR_OP, op)
297   CHECK_TARGET_DISP(5)
298   CHECK_NULL(10, MPI_ERR_ARG, request)
299
300   int retval = 0;
301
302   const SmpiBenchGuard suspend_bench;
303
304   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
305   MPI_Group group;
306   win->get_group(&group);
307   TRACE_smpi_comm_in(my_proc_id, __func__,
308                      new simgrid::instr::Pt2PtTIData(
309                          "Raccumulate", target_rank, origin_count,
310                          simgrid::smpi::Datatype::encode(origin_datatype)));
311
312   retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
313                                 target_datatype, op, request);
314
315   TRACE_smpi_comm_out(my_proc_id);
316
317   return retval;
318 }
319
320 int PMPI_Get_accumulate(const void* origin_addr, int origin_count, MPI_Datatype origin_datatype, void* result_addr,
321                         int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
322                         int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win)
323 {
324   if (op != MPI_NO_OP){
325     CHECK_BUFFER(1, origin_addr, origin_count, origin_datatype)
326     CHECK_COUNT(2, origin_count)
327     if(origin_count>0)
328       CHECK_TYPE(3, origin_datatype)
329   }
330   CHECK_COUNT(5, result_count)
331   CHECK_TYPE(6, result_datatype)
332   CHECK_BUFFER(4, result_addr, result_count, result_datatype)
333   CHECK_WIN(12, win)
334   CHECK_PROC_RMA(7, target_rank, win)
335   CHECK_COUNT(9, target_count)
336   CHECK_TYPE(10, target_datatype)
337   CHECK_MPI_NULL(11, MPI_OP_NULL, MPI_ERR_OP, op)
338   CHECK_TARGET_DISP(8)
339
340   int retval = 0;
341   const SmpiBenchGuard suspend_bench;
342
343   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
344   MPI_Group group;
345   win->get_group(&group);
346   TRACE_smpi_comm_in(my_proc_id, __func__,
347                      new simgrid::instr::Pt2PtTIData(
348                          "Get_accumulate", target_rank, target_count,
349                          simgrid::smpi::Datatype::encode(target_datatype)));
350
351   retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
352                                 result_count, result_datatype, target_rank, target_disp,
353                                 target_count, target_datatype, op);
354
355   TRACE_smpi_comm_out(my_proc_id);
356
357   return retval;
358 }
359
360 int PMPI_Rget_accumulate(const void* origin_addr, int origin_count, MPI_Datatype origin_datatype, void* result_addr,
361                          int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
362                          int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request)
363 {
364   if(target_rank==MPI_PROC_NULL)
365     *request = MPI_REQUEST_NULL;
366   if (op != MPI_NO_OP){
367     CHECK_BUFFER(1, origin_addr, origin_count, origin_datatype)
368     CHECK_COUNT(2, origin_count)
369     if(origin_count>0)
370       CHECK_TYPE(3, origin_datatype)
371   }
372   CHECK_COUNT(5, result_count)
373   CHECK_TYPE(6, result_datatype)
374   CHECK_BUFFER(4, result_addr, result_count, result_datatype)
375   CHECK_WIN(12, win)
376   CHECK_PROC_RMA(7, target_rank, win)
377   CHECK_COUNT(9, target_count)
378   CHECK_TYPE(10, target_datatype)
379   CHECK_MPI_NULL(11, MPI_OP_NULL, MPI_ERR_OP, op)
380   CHECK_TARGET_DISP(8)
381   CHECK_NULL(10, MPI_ERR_ARG, request)
382   int retval = 0;
383   const SmpiBenchGuard suspend_bench;
384
385   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
386   MPI_Group group;
387   win->get_group(&group);
388   TRACE_smpi_comm_in(my_proc_id, __func__,
389                      new simgrid::instr::Pt2PtTIData(
390                          "Rget_accumulate", target_rank, target_count,
391                          simgrid::smpi::Datatype::encode(target_datatype)));
392
393   retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
394                                 result_count, result_datatype, target_rank, target_disp,
395                                 target_count, target_datatype, op, request);
396
397   TRACE_smpi_comm_out(my_proc_id);
398
399   return retval;
400 }
401
402 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){
403   return PMPI_Get_accumulate(origin_addr, origin_addr==nullptr?0:1, dtype, result_addr, 1, dtype, target_rank, target_disp, 1, dtype, op, win);
404 }
405
406 int PMPI_Compare_and_swap(const void* origin_addr, void* compare_addr, void* result_addr, MPI_Datatype datatype,
407                           int target_rank, MPI_Aint target_disp, MPI_Win win)
408 {
409   CHECK_NULL(1, MPI_ERR_BUFFER, origin_addr)
410   CHECK_NULL(2, MPI_ERR_BUFFER, compare_addr)
411   CHECK_NULL(3, MPI_ERR_BUFFER, result_addr)
412   CHECK_TYPE(4, datatype)
413   CHECK_WIN(6, win)
414   CHECK_PROC_RMA(5, target_rank, win)
415   CHECK_TARGET_DISP(6)
416
417   int retval = 0;
418
419   const SmpiBenchGuard suspend_bench;
420
421   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
422   MPI_Group group;
423   win->get_group(&group);
424   TRACE_smpi_comm_in(my_proc_id, __func__,
425                      new simgrid::instr::Pt2PtTIData("Compare_and_swap", target_rank, 1,
426                                                      simgrid::smpi::Datatype::encode(datatype)));
427
428   retval = win->compare_and_swap(origin_addr, compare_addr, result_addr, datatype, target_rank, target_disp);
429
430   TRACE_smpi_comm_out(my_proc_id);
431
432   return retval;
433 }
434
435 int PMPI_Win_post(MPI_Group group, int assert, MPI_Win win){
436   CHECK_GROUP(1, group)
437   CHECK_WIN(2, win)
438   const SmpiBenchGuard suspend_bench;
439   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
440   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_post"));
441   int retval = win->post(group,assert);
442   TRACE_smpi_comm_out(my_proc_id);
443   return retval;
444 }
445
446 int PMPI_Win_start(MPI_Group group, int assert, MPI_Win win){
447   CHECK_GROUP(1, group)
448   CHECK_WIN(2, win)
449   const SmpiBenchGuard suspend_bench;
450   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
451   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_start"));
452   int retval = win->start(group,assert);
453   TRACE_smpi_comm_out(my_proc_id);
454   return retval;
455 }
456
457 int PMPI_Win_complete(MPI_Win win){
458   CHECK_WIN(1, win)
459   const SmpiBenchGuard suspend_bench;
460   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
461   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_complete"));
462   int retval = win->complete();
463   TRACE_smpi_comm_out(my_proc_id);
464   return retval;
465 }
466
467 int PMPI_Win_wait(MPI_Win win){
468   CHECK_WIN(1, win)
469   const SmpiBenchGuard suspend_bench;
470   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
471   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_wait"));
472   int retval = win->wait();
473   TRACE_smpi_comm_out(my_proc_id);
474   return retval;
475 }
476
477 int PMPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win){
478   CHECK_WIN(4, win)
479   CHECK_PROC_RMA(2, rank, win)
480   int retval = 0;
481   const SmpiBenchGuard suspend_bench;
482   if (lock_type != MPI_LOCK_EXCLUSIVE &&
483       lock_type != MPI_LOCK_SHARED) {
484     retval = MPI_ERR_LOCKTYPE;
485   } else {
486     aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
487     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_lock"));
488     retval = win->lock(lock_type,rank,assert);
489     TRACE_smpi_comm_out(my_proc_id);
490   }
491   return retval;
492 }
493
494 int PMPI_Win_unlock(int rank, MPI_Win win){
495   CHECK_WIN(2, win)
496   CHECK_PROC_RMA(1, rank, win)
497   const SmpiBenchGuard suspend_bench;
498   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
499   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_unlock"));
500   int retval = win->unlock(rank);
501   TRACE_smpi_comm_out(my_proc_id);
502   return retval;
503 }
504
505 int PMPI_Win_lock_all(int assert, MPI_Win win){
506   CHECK_WIN(2, win)
507   const SmpiBenchGuard suspend_bench;
508   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
509   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_lock_all"));
510   int retval = win->lock_all(assert);
511   TRACE_smpi_comm_out(my_proc_id);
512   return retval;
513 }
514
515 int PMPI_Win_unlock_all(MPI_Win win){
516   CHECK_WIN(1, win)
517   const SmpiBenchGuard suspend_bench;
518   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
519   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_unlock_all"));
520   int retval = win->unlock_all();
521   TRACE_smpi_comm_out(my_proc_id);
522   return retval;
523 }
524
525 int PMPI_Win_flush(int rank, MPI_Win win){
526   CHECK_WIN(2, win)
527   CHECK_PROC_RMA(1, rank, win)
528   const SmpiBenchGuard suspend_bench;
529   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
530   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush"));
531   int retval = win->flush(rank);
532   TRACE_smpi_comm_out(my_proc_id);
533   return retval;
534 }
535
536 int PMPI_Win_flush_local(int rank, MPI_Win win){
537   CHECK_WIN(2, win)
538   CHECK_PROC_RMA(1, rank, win)
539   const SmpiBenchGuard suspend_bench;
540   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
541   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush_local"));
542   int retval = win->flush_local(rank);
543   TRACE_smpi_comm_out(my_proc_id);
544   return retval;
545 }
546
547 int PMPI_Win_flush_all(MPI_Win win){
548   CHECK_WIN(1, win)
549   const SmpiBenchGuard suspend_bench;
550   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
551   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush_all"));
552   int retval = win->flush_all();
553   TRACE_smpi_comm_out(my_proc_id);
554   return retval;
555 }
556
557 int PMPI_Win_flush_local_all(MPI_Win win){
558   CHECK_WIN(1, win)
559   const SmpiBenchGuard suspend_bench;
560   aid_t my_proc_id = simgrid::s4u::this_actor::get_pid();
561   TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("Win_flush_local_all"));
562   int retval = win->flush_local_all();
563   TRACE_smpi_comm_out(my_proc_id);
564   return retval;
565 }
566
567 int PMPI_Win_shared_query (MPI_Win win, int rank, MPI_Aint* size, int* disp_unit, void* baseptr)
568 {
569   CHECK_WIN(1, win)
570   return win->shared_query(rank, size, disp_unit, baseptr);
571 }
572
573 int PMPI_Win_get_attr (MPI_Win win, int keyval, void *attribute_val, int* flag)
574 {
575   static MPI_Aint size;
576   static MPI_Aint disp_unit;
577   CHECK_WIN(1, win)
578   switch (keyval) {
579     case MPI_WIN_BASE:
580       *static_cast<void**>(attribute_val) = win->base();
581       *flag                               = 1;
582       return MPI_SUCCESS;
583     case MPI_WIN_SIZE:
584       size                                    = win->size();
585       *static_cast<MPI_Aint**>(attribute_val) = &size;
586       *flag                                   = 1;
587       return MPI_SUCCESS;
588     case MPI_WIN_DISP_UNIT:
589       disp_unit                               = win->disp_unit();
590       *static_cast<MPI_Aint**>(attribute_val) = &disp_unit;
591       *flag                                   = 1;
592       return MPI_SUCCESS;
593     default:
594      return win->attr_get<simgrid::smpi::Win>(keyval, attribute_val, flag);
595   }
596 }
597
598 int PMPI_Win_set_attr (MPI_Win win, int type_keyval, void *attribute_val)
599 {
600   CHECK_WIN(1, win)
601   return win->attr_put<simgrid::smpi::Win>(type_keyval, attribute_val);
602 }
603
604 int PMPI_Win_delete_attr (MPI_Win win, int type_keyval)
605 {
606   CHECK_WIN(1, win)
607   return win->attr_delete<simgrid::smpi::Win>(type_keyval);
608 }
609
610 int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
611                             void* extra_state)
612 {
613   smpi_copy_fn _copy_fn={nullptr, nullptr,copy_fn,nullptr, nullptr,nullptr};
614   smpi_delete_fn _delete_fn={nullptr, nullptr,delete_fn,nullptr, nullptr,nullptr};
615   return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
616 }
617
618 int PMPI_Win_free_keyval(int* keyval) {
619   return simgrid::smpi::Keyval::keyval_free<simgrid::smpi::Win>(keyval);
620 }
621
622 MPI_Win PMPI_Win_f2c(MPI_Fint win){
623   if(win==-1)
624     return MPI_WIN_NULL;
625   return simgrid::smpi::Win::f2c(win);
626 }
627
628 MPI_Fint PMPI_Win_c2f(MPI_Win win){
629   if(win==MPI_WIN_NULL)
630     return -1;
631   return win->c2f();
632 }
633
634 int PMPI_Win_create_errhandler(MPI_Win_errhandler_function* function, MPI_Errhandler* errhandler){
635   *errhandler=new simgrid::smpi::Errhandler(function);
636   return MPI_SUCCESS;
637 }
638
639 int PMPI_Win_get_errhandler(MPI_Win win, MPI_Errhandler* errhandler){
640   CHECK_WIN(1, win)
641   if (errhandler==nullptr){
642     return MPI_ERR_ARG;
643   }
644   *errhandler=win->errhandler();
645   return MPI_SUCCESS;
646 }
647
648 int PMPI_Win_set_errhandler(MPI_Win win, MPI_Errhandler errhandler){
649   CHECK_WIN(1, win)
650   if (errhandler==nullptr){
651     return MPI_ERR_ARG;
652   }
653   win->set_errhandler(errhandler);
654   return MPI_SUCCESS;
655 }
656
657 int PMPI_Win_call_errhandler(MPI_Win win,int errorcode){
658   CHECK_WIN(1, win)
659   MPI_Errhandler err = win->errhandler();
660   err->call(win, errorcode);
661   simgrid::smpi::Errhandler::unref(err);
662   return MPI_SUCCESS;
663 }