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

Last change on this file since 1068 was 1068, checked in by yushan, 6 years ago

minor modification for using intelmpi

File size: 8.5 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
45  class ep_communicator;
46  class ep_intercomm;
47  class OMPbarrier;
48  typedef ep_communicator* EP_Comm;
49  class MPI_Comm;
50
51
52  class MPI_Status
53  {
54    public:
55
56      #ifdef _intelmpi
57      int ep_datatype;
58      #elif _openmpi
59      void * ep_datatype;
60      #endif
61     
62      int ep_src;
63      int ep_tag;
64
65     
66      void* mpi_status;
67  };
68
69  class MPI_Message
70  {
71    public:
72
73      #ifdef _intelmpi
74      int mpi_message;
75      #elif _openmpi
76      void * mpi_message;
77      #endif
78
79      int ep_src;
80      int ep_tag;
81
82      void* mpi_status;
83
84      MPI_Message() {}
85
86      #ifdef _intelmpi
87      MPI_Message(int message): mpi_message(message) {}
88      #elif _openmpi
89      MPI_Message(void* message): mpi_message(message) {}
90      #endif
91  };
92
93  typedef std::list<MPI_Message > Message_list;
94
95
96  class OMPbarrier
97  {
98    private:
99      int nbThreads;          //<The number of threads for this barrier
100      int currentNbThread;    //<The current number of threads waiting
101      bool sense;             //<Direct barrier feedback protection
102      omp_lock_t mutex;       //<To have an atomic int
103
104      OMPbarrier(OMPbarrier&){}
105      OMPbarrier& operator=(OMPbarrier&){return *this;}
106
107    public:
108      /** Constructor with the number of threads */
109      explicit OMPbarrier(const int inNbThreads)
110          : nbThreads(inNbThreads), currentNbThread(0), sense(false) {
111          omp_init_lock( &mutex );
112      }
113
114      /** Destructor, release the omp lock */
115      ~OMPbarrier(){
116          omp_destroy_lock( &mutex );
117      }
118
119      /** Perform a barrier */
120      void wait(){
121          const bool mySense = sense;
122          omp_set_lock( &mutex );
123          const int nbThreadsArrived = (++currentNbThread);
124          omp_unset_lock( &mutex );
125
126          if(nbThreadsArrived == nbThreads) {
127              currentNbThread = 0;
128              sense = !sense;
129              #pragma omp flush
130          }
131          else {
132              volatile const bool* const ptSense = &sense;
133              while( (*ptSense) == mySense){
134              }
135          }
136      }
137
138
139      /** Change the number of threads */
140      void setNbThreads(const int inNbThread){
141          omp_set_lock( &mutex );
142          nbThreads = inNbThread;
143          omp_unset_lock( &mutex );
144      }
145  };
146
147  class ep_intercomm
148  {
149    public:
150
151
152    #ifdef _intelmpi
153    int mpi_inter_comm;
154    #elif _openmpi
155    void * mpi_inter_comm;
156    #endif
157
158    RANK_MAP *intercomm_rank_map;
159    RANK_MAP *local_rank_map;
160    RANK_MAP *remote_rank_map;
161
162
163    SIZE_RANK_INFO size_rank_info[3];
164
165
166    MPI_Comm *local_comm;
167    int intercomm_tag;
168
169    ep_intercomm()
170    {
171      intercomm_rank_map = NULL;
172      local_rank_map = NULL;
173      remote_rank_map = NULL;
174    }
175
176    bool operator == (ep_intercomm right)
177    {
178      bool a = intercomm_rank_map == right.intercomm_rank_map;
179      bool b = local_rank_map == right.local_rank_map;
180      bool c = remote_rank_map == right.remote_rank_map;
181      bool d = mpi_inter_comm == right.mpi_inter_comm;
182      bool e = size_rank_info == right.size_rank_info;
183      bool f = intercomm_tag == right.intercomm_tag;
184      return a&&b&&c&&d&&e&&f;
185    }
186
187    bool operator != (ep_intercomm right)
188    {
189      bool a = intercomm_rank_map != right.intercomm_rank_map;
190      bool b = local_rank_map != right.local_rank_map;
191      bool c = remote_rank_map != right.remote_rank_map;
192      bool d = mpi_inter_comm != right.mpi_inter_comm;
193      bool e = size_rank_info != right.size_rank_info;
194      bool f = intercomm_tag != right.intercomm_tag;
195      return a||b||c||d||e||f;
196    }
197  };
198
199
200  class ep_communicator
201  {
202    public:
203
204    SIZE_RANK_INFO size_rank_info[3]; // 0: ep_rank,     ep_size
205                                      // 1: ep_rank_loc, num_ep
206                                      // 2: mpi_rank,    mpi_size
207
208
209    MPI_Comm *comm_list;
210
211    Message_list *message_queue;
212
213
214    int comm_label;
215
216    ep_intercomm *intercomm;
217
218    ep_communicator()
219    {
220      comm_list = NULL;
221      message_queue = NULL;
222      intercomm = NULL;
223    }
224
225    bool operator == (ep_communicator right)
226    {
227      bool a = size_rank_info == right.size_rank_info;
228      bool b = comm_label == right.comm_label;
229      bool c = intercomm == right.intercomm;
230      return a&&b&&c;
231    }
232
233    bool operator != (ep_communicator right)
234    {
235      bool a = size_rank_info != right.size_rank_info;
236      bool b = comm_label != right.comm_label;
237      bool c = intercomm != right.intercomm;
238      return a||b||c;
239    }
240  };
241
242
243  struct BUFFER
244  {
245    double *buf_double;
246    float  *buf_float;
247    int    *buf_int;
248    long    *buf_long;
249    unsigned long    *buf_ulong;
250    char    *buf_char;
251  };
252
253
254  class MPI_Comm
255  {
256    public:
257
258    #ifdef _intelmpi
259    int mpi_comm;
260    #elif _openmpi
261    void * mpi_comm;
262    #endif
263
264    bool is_ep;
265    bool is_intercomm;
266
267    BUFFER     *my_buffer;
268    OMPbarrier *ep_barrier;
269    RANK_MAP   *rank_map;
270
271    EP_Comm ep_comm_ptr;
272
273    MPI_Comm *mem_bridge;
274
275    #ifdef _intelmpi
276    int mpi_bridge;
277    #elif _openmpi
278    void * mpi_bridge;
279    #endif
280
281    MPI_Comm()
282    {
283      is_ep = true;
284      is_intercomm = false;
285      my_buffer = NULL;
286      ep_barrier = NULL;
287      rank_map = NULL;
288      ep_comm_ptr = NULL;
289      mem_bridge = NULL;
290      mpi_bridge = NULL;
291    }
292
293    #ifdef _intelmpi
294    MPI_Comm(int comm)
295    {
296      is_ep = false;
297      is_intercomm = false;
298      my_buffer = NULL;
299      ep_barrier = NULL;
300      rank_map = NULL;
301      ep_comm_ptr = NULL;
302      mem_bridge = NULL;
303      mpi_bridge = NULL;
304      mpi_comm = comm;
305    }
306
307    #elif _openmpi
308
309    MPI_Comm(void* comm)
310    {
311      is_ep = false;
312      is_intercomm = false;
313      my_buffer = NULL;
314      ep_barrier = NULL;
315      rank_map = NULL;
316      ep_comm_ptr = NULL;
317      mem_bridge = NULL;
318      mpi_bridge = NULL;
319      mpi_comm = comm;
320    }
321    #endif
322
323
324    bool operator == (MPI_Comm right)
325    {
326      bool a = is_ep == right.is_ep;
327      bool b = is_intercomm == right.is_intercomm;
328      bool c = mpi_comm == right.mpi_comm;
329      bool d = is_ep ? ep_comm_ptr == right.ep_comm_ptr : true;
330      return a&&b&&c&&d;
331    }
332
333    bool operator != (MPI_Comm right)
334    {
335      bool a = is_ep != right.is_ep;
336      bool b = is_intercomm != right.is_intercomm;
337      bool c = mpi_comm != right.mpi_comm;
338      bool d = is_ep ? ep_comm_ptr != right.ep_comm_ptr : true;
339
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.