Salome HOME
998f6e8c62cd78c3c471bb8ed3b9484987436a82
[tools/medcoupling.git] / src / ParaMEDMEM / MPIAccessDEC.hxx
1 // Copyright (C) 2007-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #ifndef __MPIACCESSDEC_HXX__
21 #define __MPIACCESSDEC_HXX__
22
23 #include "MPIAccess.hxx"
24 #include "DEC.hxx"
25 #include "LinearTimeInterpolator.hxx"
26
27 #include <map>
28 #include <iostream>
29
30 namespace MEDCoupling
31 {
32   /*
33    * Internal class, not part of the public API.
34    *
35    * Another gateway to the MPI library?
36    */
37   class MPIAccessDEC
38   {
39   public:  
40     MPIAccessDEC( const ProcessorGroup& local_group, const ProcessorGroup& distant_group,
41                   bool Asynchronous = true );
42     virtual ~MPIAccessDEC();
43     MPIAccess * getMPIAccess() { return _MPI_access; }
44     const MPI_Comm* getComm() { return _MPI_union_group->getComm(); }
45     void asynchronous( bool Asynchronous = true ) { _asynchronous = Asynchronous; }
46     void setTimeInterpolator( TimeInterpolationMethod anInterp , double InterpPrecision=0 ,
47                               int n_step_before=1, int nStepAfter=1 );
48
49     void setTime( double t ) { _t = t; _dt = -1; }
50     void setTime( double t , double dt ) { _t = t; _dt = dt; }
51     bool outOfTime( int target ) { return (*_out_of_time)[target]; }
52
53     int send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target );
54     int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target );
55     int recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target ,
56               int &RecvRequestId , bool Asynchronous=false );
57     int sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype ,
58                   void* recvbuf, int recvcount , MPI_Datatype recvtype , int target );
59
60     int allToAll( void* sendbuf, int sendcount, MPI_Datatype sendtype ,
61                   void* recvbuf, int recvcount, MPI_Datatype recvtype );
62     int allToAllv( void* sendbuf, int* sendcounts, int* sdispls, MPI_Datatype sendtype ,
63                    void* recvbuf, int* recvcounts, int* rdispls, MPI_Datatype recvtype );
64
65     int allToAllTime( void* sendbuf, int sendcount , MPI_Datatype sendtype ,
66                       void* recvbuf, int recvcount , MPI_Datatype recvtype );
67     int allToAllvTime( void* sendbuf, int* sendcounts, int* sdispls,
68                        MPI_Datatype sendtype ,
69                        void* recvbuf, int* recvcounts, int* rdispls,
70                        MPI_Datatype recvtype );
71     int checkTime( int recvcount , MPI_Datatype recvtype , int target , bool UntilEnd );
72     int checkSent(bool WithWait=false);
73     int checkFinalSent() { return checkSent( true ); }
74     int checkFinalRecv();
75   protected:
76     int send( void* sendbuf, int sendcount , int sendoffset , MPI_Datatype sendtype ,
77               int target, int &SendRequestId );
78     int recv( void* recvbuf, int recvcount , int recvoffset , MPI_Datatype recvtype ,
79               int target, int &RecvRequestId );
80     int sendRecv( void* sendbuf, int sendcount , int sendoffset ,
81                   MPI_Datatype sendtype , 
82                   void* recvbuf, int recvcount , int recvoffset ,
83                   MPI_Datatype recvtype , int target ,
84                   int &SendRequestId ,int &RecvRequestId );
85   private :
86     bool _asynchronous;
87     MPIProcessorGroup* _MPI_union_group;
88
89     TimeInterpolator* _time_interpolator;
90     int _n_step_before;
91     int _n_step_after;
92
93     int _my_rank;
94     int _group_size;
95     MPIAccess* _MPI_access;
96
97     // Current time and deltatime of current process
98     double _t;
99     double _dt;
100
101     // TimeMessages from each target _TimeMessages[target][Step] : TimeMessage
102     std::vector< std::vector< TimeMessage > > *_time_messages;
103     // Corresponding DataMessages from each target _DataMessages[target][~TimeStep]
104     std::vector< bool >* _out_of_time;
105     std::vector< int >* _data_messages_recv_count;
106     std::vector< MPI_Datatype >* _data_messages_type;
107     std::vector< std::vector< void * > >* _data_messages;
108
109     typedef struct
110     {
111       void * SendBuffer;
112       int Counter;
113       MPI_Datatype DataType; }
114       SendBuffStruct;
115     std::map< int ,  SendBuffStruct * > *_map_of_send_buffers;
116   };
117
118   inline int MPIAccessDEC::send( void* sendbuf, int sendcount , MPI_Datatype sendtype , int target )
119   {
120     int SendRequestId;
121     int sts;
122     if ( _asynchronous )
123       {
124         sts = _MPI_access->ISend( sendbuf , sendcount , sendtype , target ,
125                                   SendRequestId );
126       }
127     else
128       {
129         sts = _MPI_access->send( sendbuf , sendcount , sendtype , target ,
130                                  SendRequestId );
131         if ( sts == MPI_SUCCESS )
132           free( sendbuf );
133       }
134     return sts;
135   }
136
137   inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype , int target )
138   {
139     int RecvRequestId;
140     int sts;
141     if ( _asynchronous )
142       sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target , RecvRequestId );
143     else
144       sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target ,  RecvRequestId );
145     return sts;
146   }
147
148   inline int MPIAccessDEC::recv( void* recvbuf, int recvcount , MPI_Datatype recvtype ,
149                                  int target ,  int &RecvRequestId , bool Asynchronous )
150   {
151     int sts;
152     if ( Asynchronous )
153       sts = _MPI_access->IRecv( recvbuf , recvcount , recvtype , target ,
154                                 RecvRequestId );
155     else
156       sts = _MPI_access->recv( recvbuf , recvcount , recvtype , target ,
157                                RecvRequestId );
158     return sts;
159   }
160   
161   inline int MPIAccessDEC::sendRecv( void* sendbuf, int sendcount , MPI_Datatype sendtype ,
162                                      void* recvbuf, int recvcount , MPI_Datatype recvtype ,
163                                      int target )
164   {
165     int SendRequestId;
166     int RecvRequestId;
167     int sts;
168     if ( _asynchronous )
169       sts = _MPI_access->ISendRecv( sendbuf , sendcount , sendtype , target ,
170                                     SendRequestId ,
171                                     recvbuf , recvcount , recvtype , target ,
172                                     RecvRequestId );
173     else
174       sts = _MPI_access->sendRecv( sendbuf , sendcount , sendtype , target ,
175                                    SendRequestId ,
176                                    recvbuf , recvcount , recvtype , target ,
177                                    RecvRequestId );
178     return sts;
179   }
180
181   std::ostream & operator<< (std::ostream &,const TimeInterpolationMethod &);
182 }
183
184 #endif