Logo AND Algorithmique Numérique Distribuée

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