source: XIOS/dev/branch_yushan/extern/src_ep_dev/ep_type.hpp @ 1063

Last change on this file since 1063 was 1053, checked in by yushan, 7 years ago

ep_lib namespace specified when netcdf involved

File size: 8.6 KB
Line 
1#ifndef EP_TYPE_HPP_INCLUDED
2#define EP_TYPE_HPP_INCLUDED
3
4
5#include <iostream>
6#include <stdlib.h>
7#include <stdio.h>
8#include <list>
9#include <map>
10#include <omp.h>
11#include <vector>
12#include <numeric>
13#include <bitset>
14//#include <memory.h>
15#include <algorithm>
16#include <assert.h>
17#include <math.h>
18
19#ifdef _Debug
20#define Debug(x) std::cout << x << std::endl
21#else
22#define Debug(x)
23#endif
24
25#define BUFFER_SIZE 10000
26
27typedef std::pair< int, int > SIZE_RANK_INFO; // < rank, size>
28
29typedef std::vector< std::pair<int, int> > RANK_MAP;  // at(ep_rank) = <ep_rank_local, mpi_rank>
30
31typedef std::vector<std::pair< std::pair<int, int>, std::pair<int, int> > > INTERCOMM_RANK_MAP;
32
33
34typedef struct
35{
36  int first;
37  int second;
38  int third;
39} Triple_int;
40
41namespace ep_lib
42{
43  #define MPI_UNDEFINED -32766
44  //#define MPI_STATUS_IGNORE NULL
45  //#define MPI_INFO_NULL MPI_Info(MPI_INFO_NULL_STD)
46
47  class ep_communicator;
48  class ep_intercomm;
49  class OMPbarrier;
50  typedef ep_communicator* EP_Comm;
51  class MPI_Comm;
52
53
54  class MPI_Status
55  {
56    public:
57
58      #ifdef _intelmpi
59      int ep_datatype;
60      #elif _openmpi
61      void * ep_datatype;
62      #endif
63     
64      int ep_src;
65      int ep_tag;
66
67     
68      void* mpi_status;
69  };
70
71  class MPI_Message
72  {
73    public:
74
75      #ifdef _intelmpi
76      int mpi_message;
77      #elif _openmpi
78      void * mpi_message;
79      #endif
80
81      int ep_src;
82      int ep_tag;
83
84      void* mpi_status;
85
86      MPI_Message() {}
87      #ifdef _intelmpi
88      MPI_Message(int message): mpi_message(message) {}
89      #elif _openmpi
90      MPI_Message(void* message): mpi_message(message) {}
91      #endif
92  };
93
94  typedef std::list<MPI_Message > Message_list;
95
96
97  class OMPbarrier
98  {
99    private:
100      int nbThreads;          //<The number of threads for this barrier
101      int currentNbThread;    //<The current number of threads waiting
102      bool sense;             //<Direct barrier feedback protection
103      omp_lock_t mutex;       //<To have an atomic int
104
105      OMPbarrier(OMPbarrier&){}
106      OMPbarrier& operator=(OMPbarrier&){return *this;}
107
108    public:
109      /** Constructor with the number of threads */
110      explicit OMPbarrier(const int inNbThreads)
111          : nbThreads(inNbThreads), currentNbThread(0), sense(false) {
112          omp_init_lock( &mutex );
113      }
114
115      /** Destructor, release the omp lock */
116      ~OMPbarrier(){
117          omp_destroy_lock( &mutex );
118      }
119
120      /** Perform a barrier */
121      void wait(){
122          const bool mySense = sense;
123          omp_set_lock( &mutex );
124          const int nbThreadsArrived = (++currentNbThread);
125          omp_unset_lock( &mutex );
126
127          if(nbThreadsArrived == nbThreads) {
128              currentNbThread = 0;
129              sense = !sense;
130              #pragma omp flush
131          }
132          else {
133              volatile const bool* const ptSense = &sense;
134              while( (*ptSense) == mySense){
135              }
136          }
137      }
138
139
140      /** Change the number of threads */
141      void setNbThreads(const int inNbThread){
142          omp_set_lock( &mutex );
143          nbThreads = inNbThread;
144          omp_unset_lock( &mutex );
145      }
146  };
147
148  class ep_intercomm
149  {
150    public:
151
152
153    #ifdef _intelmpi
154    int mpi_inter_comm;
155    #elif _openmpi
156    void * mpi_inter_comm;
157    #endif
158
159    RANK_MAP *intercomm_rank_map;
160    RANK_MAP *local_rank_map;
161    RANK_MAP *remote_rank_map;
162
163
164    SIZE_RANK_INFO size_rank_info[3];
165
166
167    MPI_Comm *local_comm;
168    int intercomm_tag;
169
170    ep_intercomm()
171    {
172      intercomm_rank_map = NULL;
173      local_rank_map = NULL;
174      remote_rank_map = NULL;
175    }
176
177    bool operator == (ep_intercomm right)
178    {
179      bool a = intercomm_rank_map == right.intercomm_rank_map;
180      bool b = local_rank_map == right.local_rank_map;
181      bool c = remote_rank_map == right.remote_rank_map;
182      bool d = mpi_inter_comm == right.mpi_inter_comm;
183      bool e = size_rank_info == right.size_rank_info;
184      bool f = intercomm_tag == right.intercomm_tag;
185      return a&&b&&c&&d&&e&&f;
186    }
187
188    bool operator != (ep_intercomm right)
189    {
190      bool a = intercomm_rank_map != right.intercomm_rank_map;
191      bool b = local_rank_map != right.local_rank_map;
192      bool c = remote_rank_map != right.remote_rank_map;
193      bool d = mpi_inter_comm != right.mpi_inter_comm;
194      bool e = size_rank_info != right.size_rank_info;
195      bool f = intercomm_tag != right.intercomm_tag;
196      return a||b||c||d||e||f;
197    }
198  };
199
200
201  class ep_communicator
202  {
203    public:
204
205    SIZE_RANK_INFO size_rank_info[3]; // 0: ep_rank,     ep_size
206                                      // 1: ep_rank_loc, num_ep
207                                      // 2: mpi_rank,    mpi_size
208
209
210    MPI_Comm *comm_list;
211
212    Message_list *message_queue;
213
214
215    int comm_label;
216
217    ep_intercomm *intercomm;
218
219    ep_communicator()
220    {
221      comm_list = NULL;
222      message_queue = NULL;
223      intercomm = NULL;
224    }
225
226    bool operator == (ep_communicator right)
227    {
228      bool a = size_rank_info == right.size_rank_info;
229      bool b = comm_label == right.comm_label;
230      bool c = intercomm == right.intercomm;
231      return a&&b&&c;
232    }
233
234    bool operator != (ep_communicator right)
235    {
236      bool a = size_rank_info != right.size_rank_info;
237      bool b = comm_label != right.comm_label;
238      bool c = intercomm != right.intercomm;
239      return a||b||c;
240    }
241  };
242
243
244  struct BUFFER
245  {
246    double *buf_double;
247    float  *buf_float;
248    int    *buf_int;
249    long    *buf_long;
250    unsigned long    *buf_ulong;
251    char    *buf_char;
252  };
253
254
255  class MPI_Comm
256  {
257    public:
258
259    #ifdef _intelmpi
260    int mpi_comm;
261    #elif _openmpi
262    void * mpi_comm;
263    #endif
264
265    bool is_ep;
266    bool is_intercomm;
267
268    BUFFER     *my_buffer;
269    OMPbarrier *ep_barrier;
270    RANK_MAP   *rank_map;
271
272    EP_Comm ep_comm_ptr;
273
274    MPI_Comm *mem_bridge;
275
276    #ifdef _intelmpi
277    int mpi_bridge;
278    #elif _openmpi
279    void * mpi_bridge;
280    #endif
281
282    MPI_Comm()
283    {
284      is_ep = false;
285      is_intercomm = false;
286      my_buffer = NULL;
287      ep_barrier = NULL;
288      rank_map = NULL;
289      ep_comm_ptr = NULL;
290      mem_bridge = NULL;
291      mpi_bridge = NULL;
292    }
293
294    #ifdef _intelmpi
295    MPI_Comm(int comm)
296    {
297      is_ep = false;
298      is_intercomm = false;
299      my_buffer = NULL;
300      ep_barrier = NULL;
301      rank_map = NULL;
302      ep_comm_ptr = NULL;
303      mem_bridge = NULL;
304      mpi_bridge = NULL;
305      mpi_comm = comm;
306    }
307
308    #elif _openmpi
309
310    MPI_Comm(void* comm)
311    {
312      is_ep = false;
313      is_intercomm = false;
314      my_buffer = NULL;
315      ep_barrier = NULL;
316      rank_map = NULL;
317      ep_comm_ptr = NULL;
318      mem_bridge = NULL;
319      mpi_bridge = NULL;
320      mpi_comm = comm;
321    }
322    #endif
323
324
325    bool operator == (MPI_Comm right)
326    {
327      bool a = is_ep == right.is_ep;
328      bool b = is_intercomm == right.is_intercomm;
329      bool c = mpi_comm == right.mpi_comm;
330      bool d = is_ep ? ep_comm_ptr == right.ep_comm_ptr : true;
331      return a&&b&&c&&d;
332    }
333
334    bool operator != (MPI_Comm right)
335    {
336      bool a = is_ep != right.is_ep;
337      bool b = is_intercomm != right.is_intercomm;
338      bool c = mpi_comm != right.mpi_comm;
339      bool d = is_ep ? ep_comm_ptr != right.ep_comm_ptr : true;
340      return a||b||c||d;
341    }
342  };
343
344
345  class MPI_Info
346  {
347    public:
348
349      #ifdef _intelmpi
350      int mpi_info;
351      #elif _openmpi
352      void * mpi_info;
353      #endif
354
355      MPI_Info() {}
356     
357      #ifdef _intelmpi
358      MPI_Info(int info): mpi_info(info) {}
359      #elif _openmpi
360      MPI_Info(void* info): mpi_info(info) {}
361      #endif
362  };
363
364
365  class MPI_Request
366  {
367    public:
368
369      #ifdef _intelmpi
370      int mpi_request;
371      #elif _openmpi
372      void * mpi_request;
373      #endif
374
375      int type; //! type of the non-blocking communication. 1: Isend; 2:Irecv; 3:Imrecv; 4:Issend
376      void* buf;
377
378      int ep_src;
379      int ep_tag;
380      #ifdef _intelmpi
381      int ep_datatype;
382      #elif _openmpi
383      void * ep_datatype;
384      #endif
385
386      MPI_Comm comm;    //! EP communicator related to the communication
387
388      MPI_Request() {}
389
390      #ifdef _intelmpi
391      MPI_Request(int request): mpi_request(request) {}
392      #elif _openmpi
393      MPI_Request(void* request): mpi_request(request) {}
394      #endif
395  };
396
397 
398  class MPI_Aint
399  {
400    public:
401
402    unsigned long mpi_aint;
403
404    MPI_Aint() {}
405    MPI_Aint(int a): mpi_aint(a) {}
406  };
407
408  class MPI_Fint
409  {
410    public:
411
412    int mpi_fint;
413
414    MPI_Fint() {}
415    MPI_Fint(int f): mpi_fint(f) {}
416   
417  };
418
419
420  static MPI_Comm *passage;
421
422  static int TAG = 40000;
423
424  static std::list<std::pair<std::pair<int, int>, MPI_Comm * > > tag_list;
425
426  static std::map<std::pair<int, int>, MPI_Comm  >  fc_comm_map;
427            //    <MPI_Fint,thread_num>   EP_Comm
428
429}
430
431
432
433#endif // EP_TYPE_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.