source: XIOS3/trunk/src/manager/window_base.hpp @ 2606

Last change on this file since 2606 was 2580, checked in by ymipsl, 10 months ago

Tracking unfree MPI windows and communicators.

YM

  • Property svn:executable set to *
File size: 4.4 KB
Line 
1#ifndef __WINDOW_BASE_HPP__
2#define __WINDOW_BASE_HPP__
3
4#include <map>
5#include <string>
6
7#include "exception.hpp"
8#include "mpi.hpp"
9#include <string>
10
11namespace xios
12{
13
14
15  class CWindowBase
16  {
17    private:
18      void * winBuffer_ ;   
19      const MPI_Aint OFFSET_LOCK=0 ;
20      const int SIZE_LOCK=sizeof(long) ;
21      const MPI_Aint OFFSET_BUFFER =  SIZE_LOCK ;
22      MPI_Aint bufferSize_ ;
23      MPI_Aint windowSize_ ;
24      const double maxLatency_ = 1e-3 ; // 1ms latency maximum
25      MPI_Win window_ ;
26      std::string name_ ;
27
28    public :
29
30    CWindowBase(MPI_Comm winComm, size_t bufferSize, const string name);
31
32    bool tryLockExclusive(int rank)
33    {
34      long lock = 1;
35      long unlock = 0;
36      long state;
37
38      int flag ;
39      MPI_Compare_and_swap(&lock, &unlock, &state, MPI_LONG, rank, OFFSET_LOCK, window_) ;
40      MPI_Win_flush(rank, window_);
41
42      bool locked = (state == unlock) ;
43      return locked ;
44    }
45
46    bool tryLockShared(int rank, MPI_Op op)
47    {
48      long one = 0x100000000;
49      long res;
50
51      MPI_Fetch_and_op(&one, &res, MPI_LONG, rank, OFFSET_LOCK, op, window_);
52      MPI_Win_flush(rank, window_);
53     
54      bool locked =  ! (res & 1) ;
55      return locked ;
56    }
57
58    void unlockExclusive(int rank)
59    {
60      int lock = 1;
61      int unlock = 0;
62      int state;
63
64      MPI_Win_flush(rank, window_);
65      MPI_Compare_and_swap(&unlock, &lock, &state, MPI_INT, rank, OFFSET_LOCK, window_) ;
66      MPI_Win_flush(rank, window_);
67      if (lock != state) ERROR("CWindowBase::unlockWindowExclusive",<<"unlockWindow failed: bad state"<<endl) ; 
68    }
69
70    void unlockShared(int rank)
71    {
72      int minusone = -1;
73      int res;
74      MPI_Fetch_and_op(&minusone, &res, MPI_INT, rank, OFFSET_LOCK+4, MPI_SUM, window_);
75      MPI_Win_flush(rank, window_);
76    }
77
78    void lockExclusive(int rank)
79    {
80      double time =  MPI_Wtime() ;
81      bool locked = tryLockExclusive(rank);
82      double lastTime = MPI_Wtime() ;
83      double delta = lastTime-time ;
84     
85      while (!locked)
86      {
87        time = MPI_Wtime() ;
88        if (delta > maxLatency_) delta = maxLatency_ ;
89        if (time >= lastTime+delta)
90        { 
91          locked = tryLockExclusive(rank);
92          delta=delta*2.;
93          lastTime = time ;     
94        }
95      } 
96    }
97
98    void lockShared(int rank)
99    {
100      double time =  MPI_Wtime() ;
101      bool locked = tryLockShared(rank, MPI_SUM);
102      double lastTime = MPI_Wtime() ;
103      double delta = lastTime-time ;
104     
105      while (!locked)
106      {
107        time = MPI_Wtime() ;
108        if (delta > maxLatency_) delta = maxLatency_ ;
109        if (time >= lastTime+delta)
110        { 
111          locked = tryLockShared(rank, MPI_NO_OP);
112          delta=delta*2.;
113          lastTime = time ;     
114        }
115      } 
116    }
117
118    int flush(int rank)
119    {
120      return MPI_Win_flush(rank, window_) ;
121    }
122
123    int put(const void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp,
124            int target_count, MPI_Datatype target_datatype)
125    {
126      return MPI_Put(origin_addr, origin_count, origin_datatype, target_rank,  target_disp + OFFSET_BUFFER, target_count, target_datatype, window_) ;
127    }
128
129    int get(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank, MPI_Aint target_disp,
130            int target_count, MPI_Datatype target_datatype)
131    {
132      return MPI_Get(origin_addr, origin_count, origin_datatype, target_rank, target_disp + OFFSET_BUFFER, target_count, target_datatype, window_) ;
133    }
134   
135    int fetchAndOp(const void *origin_addr, void *result_addr, MPI_Datatype datatype, int target_rank, MPI_Aint target_disp, MPI_Op op)
136    {
137      return MPI_Fetch_and_op(origin_addr, result_addr, datatype, target_rank, target_disp + OFFSET_BUFFER, op, window_ ) ;
138    }
139   
140    int compareAndSwap(const void *origin_addr, const void *compare_addr, void *result_addr, MPI_Datatype datatype,
141                       int target_rank, MPI_Aint target_disp)
142    {
143      return MPI_Compare_and_swap(origin_addr, compare_addr, result_addr, datatype, target_rank, target_disp + OFFSET_BUFFER, window_) ;
144    }
145
146    ~CWindowBase()
147    {
148      MPI_Win_unlock_all(window_);
149      info(100)<<"CWindowBase destructor : "<<name_<<endl ;
150    }
151
152  } ;
153}
154
155
156
157#endif
Note: See TracBrowser for help on using the repository browser.