Salome HOME
dbc8a3f3afd653723276cbf2dada36d540e8c2f9
[modules/med.git] / src / ParaMEDMEMTest / test_MPI_Access_Time_0.cxx
1 // Copyright (C) 2007-2013  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.
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 #include <string>
21 #include <vector>
22 #include <map>
23 #include <iostream>
24 #include <mpi.h>
25
26 #include "MPIAccessTest.hxx"
27 #include <cppunit/TestAssert.h>
28
29 //#include "CommInterface.hxx"
30 //#include "ProcessorGroup.hxx"
31 //#include "MPIProcessorGroup.hxx"
32 #include "MPIAccess.hxx"
33
34 // use this define to enable lines, execution of which leads to Segmentation Fault
35 #define ENABLE_FAULTS
36
37 // use this define to enable CPPUNIT asserts and fails, showing bugs
38 #define ENABLE_FORCED_FAILURES
39
40 using namespace std;
41 using namespace ParaMEDMEM;
42
43 void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) {
44   char msgerr[MPI_MAX_ERROR_STRING] ;
45   int lenerr ;
46   if ( sts != MPI_SUCCESS ) {
47     mpi_access->errorString(sts, msgerr, &lenerr) ;
48     cout << "test" << myrank << " lenerr " << lenerr << " "
49          << msgerr << endl ;
50     ostringstream strstream ;
51     strstream << "==========================================================="
52               << "test" << myrank << " KO"
53               << "==========================================================="
54               << endl ;
55     cout << strstream.str() << endl ;
56     CPPUNIT_FAIL( strstream.str() ) ;
57   }
58 return ;
59 }
60
61 void MPIAccessTest::test_MPI_Access_Time_0() {
62
63   cout << "test_MPI_Access_Time_0" << endl ;
64
65 //  MPI_Init(&argc, &argv) ; 
66
67   int size ;
68   int myrank ;
69   MPI_Comm_size(MPI_COMM_WORLD,&size) ;
70   MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ;
71
72   if ( size < 2 ) {
73     ostringstream strstream ;
74     strstream << "usage :" << endl
75               << "mpirun -np <nbprocs> test_MPI_Access_Time_0" <<endl
76               << " nbprocs =2" << endl
77               << "test must be runned with 2 procs" << endl ;
78     cout << strstream.str() << endl ;
79     CPPUNIT_FAIL( strstream.str() ) ;
80   }
81
82 #define maxreq 100
83
84   double t ;
85   double dt[2] = {2., 1.} ;
86   double maxt = maxreq/dt[myrank] ;
87
88   cout << "test_MPI_Access_Time_0 rank" << myrank << endl ;
89
90   ParaMEDMEM::CommInterface interface ;
91
92   ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ;
93
94   ParaMEDMEM::MPIAccess * mpi_access = new ParaMEDMEM::MPIAccess( group ) ;
95
96   if ( myrank >= 2 ) {
97     cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ;
98     mpi_access->barrier() ;
99     cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ;
100     cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ;
101     mpi_access->barrier() ;
102     cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ;
103     delete group ;
104     delete mpi_access ;
105     cout << "test_MPI_Access_Time" << myrank << " OK" << endl ;
106     return ;
107   }
108
109   int target = 1 - myrank ;
110   int SendTimeRequestId[maxreq] ;
111   int RecvTimeRequestId[maxreq] ;
112   int SendRequestId[maxreq] ;
113   int RecvRequestId[maxreq] ;
114   int sts ;
115   int sendbuf[maxreq] ;
116   int recvbuf[maxreq] ;
117   ParaMEDMEM::TimeMessage aSendTimeMsg[maxreq] ;
118   int lasttime = -1 ;
119   ParaMEDMEM::TimeMessage RecvTimeMessages[maxreq+1] ;
120   ParaMEDMEM::TimeMessage *aRecvTimeMsg = &RecvTimeMessages[1] ;
121 //  mpi_access->Trace() ;
122   int istep = 0 ;
123   for ( t = 0 ; t < maxt ; t = t+dt[myrank] ) {
124      cout << "test" << myrank << " ==========================TIME " << t
125           << " ==========================" << endl ;
126      if ( myrank == 0 ) {
127        aSendTimeMsg[istep].time = t ;
128        aSendTimeMsg[istep].deltatime = dt[myrank] ;
129        //aSendTimeMsg[istep].maxtime = maxt ;
130        if ( t+dt[myrank] >= maxt ) {
131          aSendTimeMsg[istep].deltatime = 0 ;
132        }
133        sts = mpi_access->ISend( &aSendTimeMsg[istep] , 1 ,
134                                mpi_access->timeType() , target ,
135                                SendTimeRequestId[istep]) ;
136        cout << "test" << myrank << " ISend TimeRequestId " << SendTimeRequestId[istep]
137             << " tag " << mpi_access->MPITag(SendTimeRequestId[istep]) << endl ;
138        chksts( sts , myrank , mpi_access ) ;
139        sendbuf[istep] = istep ;
140        sts = mpi_access->ISend(&sendbuf[istep],1,MPI_INT,target, SendRequestId[istep]) ;
141        cout << "test" << myrank << " ISend Data RequestId " << SendRequestId[istep]
142             << " tag " << mpi_access->MPITag(SendRequestId[istep]) << endl ;
143        chksts( sts , myrank , mpi_access ) ;
144 //CheckSent
145 //=========
146        int sendrequests[2*maxreq] ;
147        int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq ,
148                                                     sendrequests ) ;
149        int j , flag ;
150        for ( j = 0 ; j < sendreqsize ; j++ ) {
151           sts = mpi_access->test( sendrequests[j] , flag ) ;
152           chksts( sts , myrank , mpi_access ) ;
153           if ( flag ) {
154             mpi_access->deleteRequest( sendrequests[j] ) ;
155             cout << "test" << myrank << " " << j << ". " << sendrequests[j]
156                  << " sendrequest deleted" << endl ;
157           }
158        }
159      }
160      else {
161 //InitRecv
162 //========
163        if ( t == 0 ) {
164          aRecvTimeMsg[lasttime].time = 0 ;
165          sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 ,
166                                  mpi_access->timeType() ,
167                                  target , RecvTimeRequestId[lasttime+1]) ;
168          cout << "test" << myrank << " t == 0 IRecv TimeRequestId "
169               << RecvTimeRequestId[lasttime+1]
170               << " MPITag " << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] )
171               << " MPICompleted "
172               << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] ) << endl ;
173          chksts( sts , myrank , mpi_access ) ;
174        }
175        else {
176          cout << "test" << myrank << " t # 0 lasttime " << lasttime << endl ;
177 //InitialOutTime
178 //==============
179          bool outtime = false ;
180          if ( lasttime != -1 ) {
181            if ( t <= aRecvTimeMsg[lasttime-1].time ) {
182              ostringstream strstream ;
183              strstream << "==========================================================="
184                        << endl << "test" << myrank << " t " << t << " <= "
185                        << "aRecvTimeMsg[ " << lasttime << "-1 ].time "
186                        << aRecvTimeMsg[lasttime-1].time << " KO" << endl
187                        << "==========================================================="
188                        << endl ;
189              cout << strstream.str() << endl ;
190              CPPUNIT_FAIL( strstream.str() ) ;
191            }
192            else {
193              cout << "==========================================================="
194                   << endl << "test" << myrank << " t " << t << " > "
195                   << "aRecvTimeMsg[ " << lasttime << "-1 ].time "
196                   << aRecvTimeMsg[lasttime-1].time << " OK" << endl
197                   << "==========================================================="
198                   << endl ;
199            }
200            //outtime = ((aRecvTimeMsg[lasttime].time +
201            //            aRecvTimeMsg[lasttime].deltatime) >=
202            //           aRecvTimeMsg[lasttime].maxtime) ;
203            outtime = aRecvTimeMsg[lasttime].deltatime == 0 ;
204          }
205 // CheckRecv - CheckTime
206 // On a lasttime tel que :
207 // aRecvTimeMsg[ lasttime-1 ].time < T(i-1) <= aRecvTimeMsg[ lasttime ].time
208 // On cherche lasttime tel que :
209 // aRecvTimeMsg[ lasttime-1 ].time < T(i) <= aRecvTimeMsg[ lasttime ].time
210          if ( t <= aRecvTimeMsg[lasttime].time ) {
211            outtime = false ;
212          }
213          cout << "test" << myrank << " while outtime( " << outtime << " && t " << t
214               << " > aRecvTimeMsg[ " << lasttime << " ] "
215               << aRecvTimeMsg[lasttime].time << " )" << endl ;
216          while ( !outtime && (t > aRecvTimeMsg[lasttime].time) ) {
217               lasttime += 1 ;
218 //TimeMessage
219 //===========
220               sts = mpi_access->wait( RecvTimeRequestId[lasttime] ) ;
221               chksts( sts , myrank , mpi_access ) ;
222               cout << "test" << myrank << " Wait done RecvTimeRequestId "
223                    << RecvTimeRequestId[lasttime] << " lasttime " << lasttime
224                    << " tag " << mpi_access->MPITag(RecvTimeRequestId[lasttime])
225                    << aRecvTimeMsg[lasttime] << endl ;
226               if ( lasttime == 0 ) {
227                 aRecvTimeMsg[lasttime-1] = aRecvTimeMsg[lasttime] ;
228               }
229               mpi_access->deleteRequest( RecvTimeRequestId[lasttime] ) ;
230
231               double deltatime = aRecvTimeMsg[lasttime].deltatime ;
232               //double maxtime = aRecvTimeMsg[lasttime].maxtime ;
233               double nexttime = aRecvTimeMsg[lasttime].time + deltatime ;
234               cout << "test" << myrank << " t " << t << " lasttime " << lasttime
235                    << " deltatime " << deltatime
236                    << " nexttime " << nexttime << endl ;
237               //if ( nexttime < maxtime && t > nexttime ) {
238               if ( deltatime != 0 && t > nexttime ) {
239 //CheckRecv :
240 //=========   
241                 //while ( nexttime < maxtime && t > nexttime ) {
242                 while ( deltatime != 0 && t > nexttime ) {
243                      int source, MPITag, outcount ;
244                      MPI_Datatype datatype ;
245                      sts = mpi_access->probe( target , source, MPITag, datatype,
246                                              outcount ) ;
247                      chksts( sts , myrank , mpi_access ) ;
248 // Cancel DataMessages jusqu'a un TimeMessage
249                      int cancelflag ;
250                      while ( !mpi_access->isTimeMessage( MPITag ) ) {
251                           sts = mpi_access->cancel( source, MPITag, datatype, outcount ,
252                           //sts = mpi_access->cancel( source, datatype, outcount ,
253                                                    //RecvRequestId[lasttime] ,
254                                                    cancelflag ) ;
255                           cout << "test" << myrank << " Recv TO CANCEL RequestId "
256                                << RecvRequestId[lasttime]
257                                << " tag " << mpi_access->recvMPITag( target )
258                                << " cancelflag " << cancelflag << endl ;
259                           chksts( sts , myrank , mpi_access ) ;
260                           sts = mpi_access->probe( target , source, MPITag, datatype,
261                                                   outcount ) ;
262                           chksts( sts , myrank , mpi_access ) ;
263                      }
264 //On peut avancer en temps
265                      nexttime += deltatime ;
266                      //if ( nexttime < maxtime && t > nexttime ) {
267                      if ( deltatime != 0 && t > nexttime ) {
268 // Cancel du TimeMessage
269                        sts = mpi_access->cancel( source, MPITag, datatype, outcount ,
270                        //sts = mpi_access->cancel( source, datatype, outcount ,
271                                                 //RecvRequestId[lasttime] ,
272                                                 cancelflag ) ;
273                        cout << "test" << myrank << " Time TO CANCEL RequestId "
274                             << RecvRequestId[lasttime]
275                             << " tag " << mpi_access->recvMPITag( target )
276                             << " cancelflag " << cancelflag << endl ;
277                        chksts( sts , myrank , mpi_access ) ;
278                      }
279                 }
280               }
281               else {
282 //DoRecv
283 //======
284                 cout << "test" << myrank << " Recv target " << target
285                      << " lasttime " << lasttime
286                      << " lasttime-1 " << aRecvTimeMsg[lasttime-1]
287                      << " lasttime " << aRecvTimeMsg[lasttime]
288                      << endl ;
289                 sts = mpi_access->recv(&recvbuf[lasttime],1,MPI_INT,target,
290                                        RecvRequestId[lasttime]) ;
291                 cout << "test" << myrank << " Recv RequestId "
292                      << RecvRequestId[lasttime]
293                      << " tag " << mpi_access->recvMPITag( target )
294                      << endl ;
295                 chksts( sts , myrank , mpi_access ) ;
296               }
297               //outtime = ((aRecvTimeMsg[lasttime].time +
298               //            aRecvTimeMsg[lasttime].deltatime) >=
299               //           aRecvTimeMsg[lasttime].maxtime) ;
300               outtime = aRecvTimeMsg[lasttime].deltatime == 0 ;
301               if ( !outtime ) {
302 // Une lecture asynchrone d'un message temps a l'avance
303                 sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 ,
304                                         mpi_access->timeType() , target ,
305                                         RecvTimeRequestId[lasttime+1]) ;
306                 cout << "test" << myrank << " IRecv TimeRequestId "
307                      << RecvTimeRequestId[lasttime+1] << " MPITag "
308                      << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] )
309                      << " MPICompleted "
310                      << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] )
311                      << endl ;
312                 chksts( sts , myrank , mpi_access ) ;
313               }
314               else if ( t <= aRecvTimeMsg[lasttime].time ) {
315                 outtime = false ;
316               }
317          }
318          
319          //printf("DEBUG t %.15f Msg[lasttime-1] %.15f Msg[lasttime] %.15f \n",t,
320          //       aRecvTimeMsg[lasttime-1].time,aRecvTimeMsg[lasttime].time) ;
321          if ( ((t <= aRecvTimeMsg[lasttime-1].time) ||
322                (t > aRecvTimeMsg[lasttime].time)) && !outtime ) {
323            ostringstream strstream ;
324            strstream << "==========================================================="
325                      << endl << "test" << myrank << " t " << t << " <= "
326                      << "aRecvTimeMsg[ " << lasttime << "-1 ].time "
327                      << aRecvTimeMsg[lasttime-1].time << " ou t " << t << " > "
328                      << "aRecvTimeMsg[ " << lasttime << " ].time "
329                      << aRecvTimeMsg[lasttime].time << endl
330                      << " ou bien outtime " << outtime << " KO RequestTimeIds "
331                      << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime]
332                      << " RequestIds "
333                      << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl
334                      << "==========================================================="
335                      << endl ;
336            cout << strstream.str() << endl ;
337            CPPUNIT_FAIL( strstream.str() ) ;
338          }
339          else {
340            cout << "==========================================================="
341                 << endl << "test" << myrank 
342                 << " aRecvTimeMsg[ " << lasttime << "-1 ].time "
343                 << aRecvTimeMsg[lasttime-1].time << " < t " << t << " <= "
344                 << "aRecvTimeMsg[ " << lasttime << " ].time "
345                 << aRecvTimeMsg[lasttime].time << endl
346                 << " ou bien outtime " << outtime << " OK RequestTimeIds "
347                 << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime]
348                 << " RequestIds "
349                 << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl
350                 << "==========================================================="
351                 << endl ;
352          }
353        }
354      }
355      chksts( sts , myrank , mpi_access ) ;
356      istep = istep + 1 ;
357   }
358
359   cout << "test" << myrank << " Barrier :" << endl ;
360   mpi_access->barrier() ;
361
362   mpi_access->check() ;
363
364   if ( myrank == 0 ) {
365 //CheckFinalSent
366 //==============
367     cout << "test" << myrank << " CheckFinalSent :" << endl ;
368     int sendrequests[2*maxreq] ;
369     int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ;
370     int j ;
371     for ( j = 0 ; j < sendreqsize ; j++ ) {
372        sts = mpi_access->wait( sendrequests[j] ) ;
373        chksts( sts , myrank , mpi_access ) ;
374        mpi_access->deleteRequest( sendrequests[j] ) ;
375        cout << "test" << myrank << " " << j << ". " << sendrequests[j] << " deleted"
376             << endl ;
377     }
378   }
379   else {
380     cout << "test" << myrank << " CheckFinalRecv :" << endl ;
381     int recvrequests[2*maxreq] ;
382     int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ;
383     int cancelflag ;
384     int j ;
385     for ( j = 0 ; j < recvreqsize ; j++ ) {
386        sts = mpi_access->cancel( recvrequests[j] , cancelflag ) ;
387        chksts( sts , myrank , mpi_access ) ;
388        mpi_access->deleteRequest( recvrequests[j] ) ;
389        cout << "test" << myrank << " " << j << ". " << recvrequests[j] << " deleted"
390             << " cancelflag " << cancelflag << endl ;
391     }
392     int source, MPITag, outcount , flag ;
393     MPI_Datatype datatype ;
394     sts = mpi_access->IProbe( target , source, MPITag, datatype,
395                              outcount , flag ) ;
396     chksts( sts , myrank , mpi_access ) ;
397     while ( flag ) {
398          sts = mpi_access->cancel( source, MPITag, datatype, outcount ,
399          //sts = mpi_access->cancel( source, datatype, outcount ,
400                                   //RecvRequestId[lasttime] ,
401                                   cancelflag ) ;
402          cout << "test" << myrank << " TO CANCEL RequestId "
403               << RecvRequestId[lasttime]
404               << " tag " << mpi_access->recvMPITag( target )
405               << " cancelflag " << cancelflag << endl ;
406          chksts( sts , myrank , mpi_access ) ;
407          sts = mpi_access->IProbe( target , source, MPITag, datatype,
408                                   outcount , flag ) ;
409          chksts( sts , myrank , mpi_access ) ;
410     }
411   }
412   mpi_access->check() ;
413
414   if ( myrank == 0 ) {
415     int sendrequests[2*maxreq] ;
416     int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ;
417     if ( sendreqsize != 0 ) {
418       ostringstream strstream ;
419       strstream << "=========================================================" << endl
420                 << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl
421                 << "=========================================================" << endl ;
422       cout << strstream.str() << endl ;
423       CPPUNIT_FAIL( strstream.str() ) ;
424     }
425     else {
426       cout << "=========================================================" << endl
427            << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl
428            << "=========================================================" << endl ;
429     }
430   }
431   else {
432     int recvrequests[2*maxreq] ;
433     int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ;
434     if ( recvreqsize != 0 ) {
435       ostringstream strstream ;
436       strstream << "=========================================================" << endl
437                 << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl
438                 << "=========================================================" << endl ;
439       cout << strstream.str() << endl ;
440       CPPUNIT_FAIL( strstream.str() ) ;
441     }
442     else {
443       cout << "=========================================================" << endl
444            << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl
445            << "=========================================================" << endl ;
446     }
447   }
448
449   int i ;
450   for ( i = 0 ; i <= lasttime ; i++ ) {
451      cout << "test" << myrank << " " << i << ". RecvTimeMsg "
452           << aRecvTimeMsg[i].time << " recvbuf " << recvbuf[i] << endl ;
453   }
454
455   cout << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ;
456   mpi_access->barrier() ;
457   cout << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ;
458
459   delete group ;
460   delete mpi_access ;
461
462 //  MPI_Finalize();
463
464   cout << "test" << myrank << " OK" << endl ;
465
466   return ;
467 }
468
469
470
471