Salome HOME
5261cb9bf24f7a40e24c585c30f76a186a2a4abf
[tools/medcoupling.git] / src / ParaMEDMEMTest / test_AllToAllvTimeDoubleDEC.cxx
1 // Copyright (C) 2007-2016  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 #include <math.h>
21 #include <string>
22 #include <vector>
23 #include <map>
24 #include <iostream>
25 #include <mpi.h>
26 #include <ctime>
27
28 #include "MPIAccessDECTest.hxx"
29 #include <cppunit/TestAssert.h>
30
31 //#include "CommInterface.hxx"
32 //#include "ProcessorGroup.hxx"
33 //#include "MPIProcessorGroup.hxx"
34 #include "MPIAccessDEC.hxx"
35 #include "LinearTimeInterpolator.hxx"
36
37 // use this define to enable lines, execution of which leads to Segmentation Fault
38 #define ENABLE_FAULTS
39
40 // use this define to enable CPPUNIT asserts and fails, showing bugs
41 #define ENABLE_FORCED_FAILURES
42
43 using namespace std;
44 using namespace MEDCoupling;
45
46 void MPIAccessDECTest::test_AllToAllvTimeDoubleDECSynchronousPointToPoint() {
47   test_AllToAllvTimeDoubleDEC( false ) ;
48 }
49 void MPIAccessDECTest::test_AllToAllvTimeDoubleDECAsynchronousPointToPoint() {
50   test_AllToAllvTimeDoubleDEC( true ) ;
51 }
52
53 static void chksts( int sts , int myrank , MEDCoupling::MPIAccess * mpi_access ) {
54   char msgerr[MPI_MAX_ERROR_STRING] ;
55   int lenerr ;
56   if ( sts != MPI_SUCCESS ) {
57     mpi_access->errorString(sts, msgerr, &lenerr) ;
58     debugStream << "test" << myrank << " lenerr " << lenerr << " "
59          << msgerr << endl ;
60     ostringstream strstream ;
61     strstream << "==========================================================="
62               << "test" << myrank << " KO"
63               << "==========================================================="
64               << endl ;
65     debugStream << strstream.str() << endl ;
66     CPPUNIT_FAIL( strstream.str() ) ;
67   }
68   return ;
69 }
70
71 void MPIAccessDECTest::test_AllToAllvTimeDoubleDEC( bool Asynchronous ) {
72
73   debugStream << "test_AllToAllvTimeDoubleDEC" << endl ;
74
75 //  MPI_Init(&argc, &argv) ; 
76
77   int size ;
78   int myrank ;
79   MPI_Comm_size(MPI_COMM_WORLD,&size) ;
80   MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ;
81
82   if ( size < 2 || size > 11 ) {
83     ostringstream strstream ;
84     strstream << "usage :" << endl
85               << "mpirun -np <nbprocs> test_AllToAllTimeDEC" << endl
86               << " (nbprocs >=2)" << endl
87               << "test must be runned with more than 1 proc and less than 12 procs"
88               << endl ;
89     cerr << strstream.str() << endl ;
90     CPPUNIT_FAIL( strstream.str() ) ;
91   }
92
93 //  int Asynchronous = atoi(argv[1]) ;
94
95   debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " Asynchronous " << Asynchronous << endl ;
96
97   MEDCoupling::CommInterface interface ;
98   std::set<int> sourceprocs;
99   std::set<int> targetprocs;
100   int i ;
101   for ( i = 0 ; i < size/2 ; i++ ) {
102      sourceprocs.insert(i);
103   }
104   for ( i = size/2 ; i < size ; i++ ) {
105      targetprocs.insert(i);
106   }
107
108   MEDCoupling::MPIProcessorGroup* sourcegroup = new MEDCoupling::MPIProcessorGroup(interface,sourceprocs) ;
109   MEDCoupling::MPIProcessorGroup* targetgroup = new MEDCoupling::MPIProcessorGroup(interface,targetprocs) ;
110
111 //  TimeInterpolator * aLinearInterpDEC = new LinearTimeInterpolator( 0 ) ;
112   MPIAccessDEC * MyMPIAccessDEC = new MPIAccessDEC( *sourcegroup , *targetgroup ,
113                                                     Asynchronous ) ;
114 //                                                    Asynchronous , LinearInterp , 0.5 ) ;
115   MyMPIAccessDEC->setTimeInterpolator( LinearTimeInterp ) ;
116   MPIAccess * mpi_access = MyMPIAccessDEC->getMPIAccess() ;
117
118   debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " Barrier :" << endl ;
119   mpi_access->barrier() ;
120
121 #define maxproc 11
122 #define maxreq 100
123 #define datamsglength 10
124
125   int sts ;
126   int *sendcounts = new int[size] ;
127   int *sdispls = new int[size] ;
128   int *recvcounts = new int[size] ;
129   int *rdispls = new int[size] ;
130   int *sendtimecounts = new int[size] ;
131   int *stimedispls = new int[size] ;
132   int *recvtimecounts = new int[size] ;
133   int *rtimedispls = new int[size] ;
134   for ( i = 0 ; i < size ; i++ ) {
135      sendcounts[i] = datamsglength-i ;
136      sdispls[i] = i*datamsglength ;
137      recvcounts[i] = datamsglength-myrank ;
138      rdispls[i] = i*datamsglength ;
139      sendtimecounts[i] = 1 ;
140      stimedispls[i] = 0 ;
141      recvtimecounts[i] = 1 ;
142      rtimedispls[i] = i ;
143   }
144
145   double timeLoc[maxproc] ;
146   double deltatime[maxproc] = {1.,2.1,3.2,4.3,5.4,6.5,7.6,8.7,9.8,10.9,11.} ;
147   double maxtime[maxproc] ;
148   double nextdeltatime[maxproc] ;
149   for ( i = 0 ; i < size ; i++ ) {
150      timeLoc[i] = 0 ;
151      maxtime[i] = maxreq ;
152      nextdeltatime[i] = deltatime[i] ;
153   }
154   time_t begintime = time(NULL) ;
155   for ( timeLoc[myrank] = 0 ; timeLoc[myrank] <= maxtime[myrank] && nextdeltatime[myrank] != 0 ;
156         timeLoc[myrank]+=nextdeltatime[myrank] ) {
157 //local and target times
158      int target ;
159      for ( target = 0 ; target < size ; target++ ) {
160         nextdeltatime[target] = deltatime[target] ;
161         if ( timeLoc[target] != 0 ) {
162           if ( timeLoc[target]+nextdeltatime[target] > maxtime[target] ) {
163             nextdeltatime[target] = 0 ;
164           }
165         }
166         if ( target != myrank ) {
167           while ( timeLoc[myrank] >= timeLoc[target] ) {
168                timeLoc[target] += deltatime[target] ;
169           }
170         }
171      }
172      MyMPIAccessDEC->setTime( timeLoc[myrank] , nextdeltatime[myrank] ) ;
173      debugStream << "test" << myrank << "=====TIME " << timeLoc[myrank] << "=====DELTATIME "
174           << nextdeltatime[myrank] << "=====MAXTIME " << maxtime[myrank] << " ======"
175           << endl ; 
176      double * sendbuf = new double[datamsglength*size] ;
177 //     double * sendbuf = (double *) malloc(sizeof(double)*datamsglength*size) ;
178      double * recvbuf = new double[datamsglength*size] ;
179      int j ;
180      //debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " sendbuf" ;
181      for ( target = 0 ; target < size ; target++ ) {
182         for ( j = 0 ; j < datamsglength ; j++ ) {
183            //sendbuf[j] = myrank*10000 + (j/datamsglength)*100 + j ;
184            sendbuf[target*datamsglength+j] = myrank*1000000 + target*10000 +
185                                              (timeLoc[myrank]/deltatime[myrank])*100 + j ;
186            //debugStream << " " << (int ) sendbuf[target*datamsglength+j] ;
187            recvbuf[target*datamsglength+j] = -1 ;
188         }
189         //debugStream << endl ;
190      }
191
192      int sts = MyMPIAccessDEC->allToAllvTime( sendbuf, sendcounts , sdispls , MPI_DOUBLE ,
193                                             recvbuf, recvcounts , rdispls , MPI_DOUBLE ) ;
194      chksts( sts , myrank , mpi_access ) ;
195
196 //     debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf before CheckSent" ;
197 //     for ( i = 0 ; i < datamsglength*size ; i++ ) {
198 //        debugStream << " " << recvbuf[i] ;
199 //     }
200 //     debugStream << endl ;
201
202      int nRecvReq = mpi_access->recvRequestIdsSize() ;
203      if ( nRecvReq != 0 ) {
204        ostringstream strstream ;
205        strstream << "=============================================================" << endl
206                  << "test_AllToAllvTimeDoubleDEC" << myrank << " WaitAllRecv "
207                  << nRecvReq << " Requests # 0 ERROR"
208                  << endl << "============================================================"
209                  << endl ;
210        int *ArrayOfRecvRequests = new int[nRecvReq] ;
211        int nReq = mpi_access->recvRequestIds( nRecvReq, ArrayOfRecvRequests ) ;
212        mpi_access->waitAll( nReq , ArrayOfRecvRequests ) ;
213        delete [] ArrayOfRecvRequests ;
214        debugStream << strstream.str() << endl ;
215        CPPUNIT_FAIL( strstream.str() ) ;
216      }
217
218 //     debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " check of recvbuf" << endl ;
219      bool badrecvbuf = false ;
220      for ( target = 0 ; target < size ; target++ ) {
221         int j ;
222         for ( j = 0 ; j < datamsglength ; j++ ) {
223            int index = target*datamsglength+j ;
224            if ( j < recvcounts[target] ) {
225              if ( fabs(recvbuf[index] - (target*1000000 + myrank*10000 +
226                   (timeLoc[target]/deltatime[target])*100 + j)) > 101) {
227                badrecvbuf = true ;
228                debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " target " << target << " timeLoc[target] "
229                     << timeLoc[target] << " recvbuf[" << index << "] " << (int ) recvbuf[index]
230                     << " # " << (int ) (target*1000000 +
231                        myrank*10000 + (timeLoc[target]/deltatime[target])*100 + j)
232                     << endl ;
233              }
234              else if ( badrecvbuf ) {
235                debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf[" << index << "] "
236                     << recvbuf[index] << " ~= " << (int ) (target*1000000 +
237                        myrank*10000 + (timeLoc[target]/deltatime[target])*100 + j) << endl ;
238              }
239            }
240            else if ( recvbuf[index] != -1 ) {
241              badrecvbuf = true ;
242              debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " recvbuf[" << index << "] "
243                   << recvbuf[index] << " # -1" << endl ;
244            }
245         }
246      }
247      if ( badrecvbuf ) {
248        ostringstream strstream ;
249        strstream << "==================================================================" << endl
250                  << "test_AllToAllvTimeDoubleDEC" << myrank << " badrecvbuf"
251                  << endl << "=================================================================="
252                  << endl ;
253        debugStream << strstream.str() << endl ;
254        CPPUNIT_FAIL( strstream.str() ) ;
255      }
256      delete [] recvbuf ;
257   }
258
259   debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " Barrier :" << endl ;
260   mpi_access->barrier() ;
261
262   debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalSent" << endl ;
263   sts = MyMPIAccessDEC->checkFinalSent() ;
264   if ( sts != MPI_SUCCESS ) {
265     ostringstream strstream ;
266     strstream << "=================================================================" << endl
267               << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalSent ERROR"
268               << endl << "================================================================="
269               << endl ;
270     debugStream << strstream.str() << endl ;
271     CPPUNIT_FAIL( strstream.str() ) ;
272   }
273
274   debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalRecv" << endl ;
275   sts = MyMPIAccessDEC->checkFinalRecv() ;
276   if ( sts != MPI_SUCCESS ) {
277     ostringstream strstream ;
278     strstream << "=================================================================" << endl
279               << "test_AllToAllvTimeDoubleDEC" << myrank << " CheckFinalRecv ERROR"
280               << endl << "================================================================"
281               << endl ;
282     debugStream << strstream.str() << endl ;
283     CPPUNIT_FAIL( strstream.str() ) ;
284   }
285
286   int nRecvReq = mpi_access->recvRequestIdsSize() ;
287   if ( nRecvReq ) {
288     ostringstream strstream ;
289     strstream << "===============================================================" << endl
290               << "test_AllToAllvTimeDoubleDEC" << myrank << " RecvRequestIds " << nRecvReq
291               << " RecvRequests # 0 Error"
292               << endl << "==============================================================="
293               << endl ;
294     debugStream << strstream.str() << endl ;
295     CPPUNIT_FAIL( strstream.str() ) ;
296   }
297   else {
298     debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " RecvRequestIds " << nRecvReq
299          << " RecvRequests = 0 OK" << endl ;
300   }
301
302   time_t endtime = time(NULL) ;
303   debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " begintime " << begintime << " endtime " << endtime
304        << " elapse " << endtime-begintime << " " << maxtime[myrank]/deltatime[myrank]
305        << " calls to AllToAll" << endl ;
306
307   debugStream << "test" << myrank << " Barrier :" << endl ;
308   mpi_access->barrier() ;
309
310   delete sourcegroup ;
311   delete targetgroup ;
312   delete MyMPIAccessDEC ;
313 //  delete aLinearInterpDEC ;
314
315   delete [] sendcounts ;
316   delete [] sdispls ;
317   delete [] recvcounts ;
318   delete [] rdispls ;
319   delete [] sendtimecounts ;
320   delete [] stimedispls ;
321   delete [] recvtimecounts ;
322   delete [] rtimedispls ;
323
324 //  MPI_Finalize();
325
326   endtime = time(NULL) ;
327
328   debugStream << "test_AllToAllvTimeDoubleDEC" << myrank << " OK begintime " << begintime << " endtime " << endtime
329        << " elapse " << endtime-begintime << " " << maxtime[myrank]/deltatime[myrank]
330        << " calls to AllToAll" << endl ;
331
332   return ;
333 }
334
335
336
337