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