1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
26 #include "MPIAccessTest.hxx"
27 #include <cppunit/TestAssert.h>
29 //#include "CommInterface.hxx"
30 //#include "ProcessorGroup.hxx"
31 //#include "MPIProcessorGroup.hxx"
32 #include "MPIAccess.hxx"
34 // use this define to enable lines, execution of which leads to Segmentation Fault
37 // use this define to enable CPPUNIT asserts and fails, showing bugs
38 #define ENABLE_FORCED_FAILURES
41 using namespace MEDCoupling;
43 void chksts( int sts , int myrank , MEDCoupling::MPIAccess * mpi_access ) {
44 char msgerr[MPI_MAX_ERROR_STRING] ;
46 if ( sts != MPI_SUCCESS ) {
47 mpi_access->errorString(sts, msgerr, &lenerr) ;
48 debugStream << "test" << myrank << " lenerr " << lenerr << " "
50 ostringstream strstream ;
51 strstream << "==========================================================="
52 << "test" << myrank << " KO"
53 << "==========================================================="
55 debugStream << strstream.str() << endl ;
56 CPPUNIT_FAIL( strstream.str() ) ;
61 void MPIAccessTest::test_MPI_Access_Time_0() {
63 debugStream << "test_MPI_Access_Time_0" << endl ;
65 // MPI_Init(&argc, &argv) ;
69 MPI_Comm_size(MPI_COMM_WORLD,&size) ;
70 MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ;
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 run with 2 procs" << endl ;
78 cerr << strstream.str() << endl ;
79 //CPPUNIT_FAIL( strstream.str() ) ;
86 double dt[2] = {2., 1.} ;
87 double maxt = maxreq/dt[myrank] ;
89 debugStream << "test_MPI_Access_Time_0 rank" << myrank << endl ;
91 MEDCoupling::CommInterface interface ;
93 MEDCoupling::MPIProcessorGroup* group = new MEDCoupling::MPIProcessorGroup(interface) ;
95 MEDCoupling::MPIAccess * mpi_access = new MEDCoupling::MPIAccess( group ) ;
98 debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ;
99 mpi_access->barrier() ;
100 debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ;
101 debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ;
102 mpi_access->barrier() ;
103 debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ;
106 debugStream << "test_MPI_Access_Time" << myrank << " OK" << endl ;
110 int target = 1 - myrank ;
111 int SendTimeRequestId[maxreq] ;
112 int RecvTimeRequestId[maxreq] ;
113 int SendRequestId[maxreq] ;
114 int RecvRequestId[maxreq] ;
116 int sendbuf[maxreq] ;
117 int recvbuf[maxreq] ;
118 MEDCoupling::TimeMessage aSendTimeMsg[maxreq] ;
120 MEDCoupling::TimeMessage RecvTimeMessages[maxreq+1] ;
121 MEDCoupling::TimeMessage *aRecvTimeMsg = &RecvTimeMessages[1] ;
122 // mpi_access->Trace() ;
124 for ( t = 0 ; t < maxt ; t = t+dt[myrank] ) {
125 debugStream << "test" << myrank << " ==========================TIME " << t
126 << " ==========================" << endl ;
128 aSendTimeMsg[istep].time = t ;
129 aSendTimeMsg[istep].deltatime = dt[myrank] ;
130 //aSendTimeMsg[istep].maxtime = maxt ;
131 if ( t+dt[myrank] >= maxt ) {
132 aSendTimeMsg[istep].deltatime = 0 ;
134 sts = mpi_access->ISend( &aSendTimeMsg[istep] , 1 ,
135 mpi_access->timeType() , target ,
136 SendTimeRequestId[istep]) ;
137 debugStream << "test" << myrank << " ISend TimeRequestId " << SendTimeRequestId[istep]
138 << " tag " << mpi_access->MPITag(SendTimeRequestId[istep]) << endl ;
139 chksts( sts , myrank , mpi_access ) ;
140 sendbuf[istep] = istep ;
141 sts = mpi_access->ISend(&sendbuf[istep],1,MPI_INT,target, SendRequestId[istep]) ;
142 debugStream << "test" << myrank << " ISend Data RequestId " << SendRequestId[istep]
143 << " tag " << mpi_access->MPITag(SendRequestId[istep]) << endl ;
144 chksts( sts , myrank , mpi_access ) ;
147 int sendrequests[2*maxreq] ;
148 int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq ,
151 for ( j = 0 ; j < sendreqsize ; j++ ) {
152 sts = mpi_access->test( sendrequests[j] , flag ) ;
153 chksts( sts , myrank , mpi_access ) ;
155 mpi_access->deleteRequest( sendrequests[j] ) ;
156 debugStream << "test" << myrank << " " << j << ". " << sendrequests[j]
157 << " sendrequest deleted" << endl ;
165 aRecvTimeMsg[lasttime].time = 0 ;
166 sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 ,
167 mpi_access->timeType() ,
168 target , RecvTimeRequestId[lasttime+1]) ;
169 debugStream << "test" << myrank << " t == 0 IRecv TimeRequestId "
170 << RecvTimeRequestId[lasttime+1]
171 << " MPITag " << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] )
173 << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] ) << endl ;
174 chksts( sts , myrank , mpi_access ) ;
177 debugStream << "test" << myrank << " t # 0 lasttime " << lasttime << endl ;
180 bool outtime = false ;
181 if ( lasttime != -1 ) {
182 if ( t <= aRecvTimeMsg[lasttime-1].time ) {
183 ostringstream strstream ;
184 strstream << "==========================================================="
185 << endl << "test" << myrank << " t " << t << " <= "
186 << "aRecvTimeMsg[ " << lasttime << "-1 ].time "
187 << aRecvTimeMsg[lasttime-1].time << " KO" << endl
188 << "==========================================================="
190 debugStream << strstream.str() << endl ;
191 CPPUNIT_FAIL( strstream.str() ) ;
194 debugStream << "==========================================================="
195 << endl << "test" << myrank << " t " << t << " > "
196 << "aRecvTimeMsg[ " << lasttime << "-1 ].time "
197 << aRecvTimeMsg[lasttime-1].time << " OK" << endl
198 << "==========================================================="
201 //outtime = ((aRecvTimeMsg[lasttime].time +
202 // aRecvTimeMsg[lasttime].deltatime) >=
203 // aRecvTimeMsg[lasttime].maxtime) ;
204 outtime = aRecvTimeMsg[lasttime].deltatime == 0 ;
206 // CheckRecv - CheckTime
207 // On a lasttime tel que :
208 // aRecvTimeMsg[ lasttime-1 ].time < T(i-1) <= aRecvTimeMsg[ lasttime ].time
209 // On cherche lasttime tel que :
210 // aRecvTimeMsg[ lasttime-1 ].time < T(i) <= aRecvTimeMsg[ lasttime ].time
211 if ( t <= aRecvTimeMsg[lasttime].time ) {
214 debugStream << "test" << myrank << " while outtime( " << outtime << " && t " << t
215 << " > aRecvTimeMsg[ " << lasttime << " ] "
216 << aRecvTimeMsg[lasttime].time << " )" << endl ;
217 while ( !outtime && (t > aRecvTimeMsg[lasttime].time) ) {
221 sts = mpi_access->wait( RecvTimeRequestId[lasttime] ) ;
222 chksts( sts , myrank , mpi_access ) ;
223 debugStream << "test" << myrank << " Wait done RecvTimeRequestId "
224 << RecvTimeRequestId[lasttime] << " lasttime " << lasttime
225 << " tag " << mpi_access->MPITag(RecvTimeRequestId[lasttime])
226 << aRecvTimeMsg[lasttime] << endl ;
227 if ( lasttime == 0 ) {
228 aRecvTimeMsg[lasttime-1] = aRecvTimeMsg[lasttime] ;
230 mpi_access->deleteRequest( RecvTimeRequestId[lasttime] ) ;
232 double deltatime = aRecvTimeMsg[lasttime].deltatime ;
233 //double maxtime = aRecvTimeMsg[lasttime].maxtime ;
234 double nexttime = aRecvTimeMsg[lasttime].time + deltatime ;
235 debugStream << "test" << myrank << " t " << t << " lasttime " << lasttime
236 << " deltatime " << deltatime
237 << " nexttime " << nexttime << endl ;
238 //if ( nexttime < maxtime && t > nexttime ) {
239 if ( deltatime != 0 && t > nexttime ) {
242 //while ( nexttime < maxtime && t > nexttime ) {
243 while ( deltatime != 0 && t > nexttime ) {
244 int source, MPITag, outcount ;
245 MPI_Datatype datatype ;
246 sts = mpi_access->probe( target , source, MPITag, datatype,
248 chksts( sts , myrank , mpi_access ) ;
249 // Cancel DataMessages jusqu'a un TimeMessage
251 while ( !mpi_access->isTimeMessage( MPITag ) ) {
252 sts = mpi_access->cancel( source, MPITag, datatype, outcount ,
253 //sts = mpi_access->cancel( source, datatype, outcount ,
254 //RecvRequestId[lasttime] ,
256 debugStream << "test" << myrank << " Recv TO CANCEL RequestId "
257 << RecvRequestId[lasttime]
258 << " tag " << mpi_access->recvMPITag( target )
259 << " cancelflag " << cancelflag << endl ;
260 chksts( sts , myrank , mpi_access ) ;
261 sts = mpi_access->probe( target , source, MPITag, datatype,
263 chksts( sts , myrank , mpi_access ) ;
265 //On peut avancer en temps
266 nexttime += deltatime ;
267 //if ( nexttime < maxtime && t > nexttime ) {
268 if ( deltatime != 0 && t > nexttime ) {
269 // Cancel du TimeMessage
270 sts = mpi_access->cancel( source, MPITag, datatype, outcount ,
271 //sts = mpi_access->cancel( source, datatype, outcount ,
272 //RecvRequestId[lasttime] ,
274 debugStream << "test" << myrank << " Time TO CANCEL RequestId "
275 << RecvRequestId[lasttime]
276 << " tag " << mpi_access->recvMPITag( target )
277 << " cancelflag " << cancelflag << endl ;
278 chksts( sts , myrank , mpi_access ) ;
285 debugStream << "test" << myrank << " Recv target " << target
286 << " lasttime " << lasttime
287 << " lasttime-1 " << aRecvTimeMsg[lasttime-1]
288 << " lasttime " << aRecvTimeMsg[lasttime]
290 sts = mpi_access->recv(&recvbuf[lasttime],1,MPI_INT,target,
291 RecvRequestId[lasttime]) ;
292 debugStream << "test" << myrank << " Recv RequestId "
293 << RecvRequestId[lasttime]
294 << " tag " << mpi_access->recvMPITag( target )
296 chksts( sts , myrank , mpi_access ) ;
298 //outtime = ((aRecvTimeMsg[lasttime].time +
299 // aRecvTimeMsg[lasttime].deltatime) >=
300 // aRecvTimeMsg[lasttime].maxtime) ;
301 outtime = aRecvTimeMsg[lasttime].deltatime == 0 ;
303 // Une lecture asynchrone d'un message temps a l'avance
304 sts = mpi_access->IRecv( &aRecvTimeMsg[lasttime+1] , 1 ,
305 mpi_access->timeType() , target ,
306 RecvTimeRequestId[lasttime+1]) ;
307 debugStream << "test" << myrank << " IRecv TimeRequestId "
308 << RecvTimeRequestId[lasttime+1] << " MPITag "
309 << mpi_access->MPITag( RecvTimeRequestId[lasttime+1] )
311 << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] )
313 chksts( sts , myrank , mpi_access ) ;
315 else if ( t <= aRecvTimeMsg[lasttime].time ) {
320 //printf("DEBUG t %.15f Msg[lasttime-1] %.15f Msg[lasttime] %.15f \n",t,
321 // aRecvTimeMsg[lasttime-1].time,aRecvTimeMsg[lasttime].time) ;
322 if ( ((t <= aRecvTimeMsg[lasttime-1].time) ||
323 (t > aRecvTimeMsg[lasttime].time)) && !outtime ) {
324 ostringstream strstream ;
325 strstream << "==========================================================="
326 << endl << "test" << myrank << " t " << t << " <= "
327 << "aRecvTimeMsg[ " << lasttime << "-1 ].time "
328 << aRecvTimeMsg[lasttime-1].time << " ou t " << t << " > "
329 << "aRecvTimeMsg[ " << lasttime << " ].time "
330 << aRecvTimeMsg[lasttime].time << endl
331 << " ou bien outtime " << outtime << " KO RequestTimeIds "
332 << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime]
334 << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl
335 << "==========================================================="
337 debugStream << strstream.str() << endl ;
338 CPPUNIT_FAIL( strstream.str() ) ;
341 debugStream << "==========================================================="
342 << endl << "test" << myrank
343 << " aRecvTimeMsg[ " << lasttime << "-1 ].time "
344 << aRecvTimeMsg[lasttime-1].time << " < t " << t << " <= "
345 << "aRecvTimeMsg[ " << lasttime << " ].time "
346 << aRecvTimeMsg[lasttime].time << endl
347 << " ou bien outtime " << outtime << " OK RequestTimeIds "
348 << RecvTimeRequestId[lasttime-1] << " " << RecvTimeRequestId[lasttime]
350 << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl
351 << "==========================================================="
356 chksts( sts , myrank , mpi_access ) ;
360 debugStream << "test" << myrank << " Barrier :" << endl ;
361 mpi_access->barrier() ;
363 if (MPI_ACCESS_VERBOSE) mpi_access->check() ;
368 debugStream << "test" << myrank << " CheckFinalSent :" << endl ;
369 int sendrequests[2*maxreq] ;
370 int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ;
372 for ( j = 0 ; j < sendreqsize ; j++ ) {
373 sts = mpi_access->wait( sendrequests[j] ) ;
374 chksts( sts , myrank , mpi_access ) ;
375 mpi_access->deleteRequest( sendrequests[j] ) ;
376 debugStream << "test" << myrank << " " << j << ". " << sendrequests[j] << " deleted"
381 debugStream << "test" << myrank << " CheckFinalRecv :" << endl ;
382 int recvrequests[2*maxreq] ;
383 int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ;
386 for ( j = 0 ; j < recvreqsize ; j++ ) {
387 sts = mpi_access->cancel( recvrequests[j] , cancelflag ) ;
388 chksts( sts , myrank , mpi_access ) ;
389 mpi_access->deleteRequest( recvrequests[j] ) ;
390 debugStream << "test" << myrank << " " << j << ". " << recvrequests[j] << " deleted"
391 << " cancelflag " << cancelflag << endl ;
393 int source, MPITag, outcount , flag ;
394 MPI_Datatype datatype ;
395 sts = mpi_access->IProbe( target , source, MPITag, datatype,
397 chksts( sts , myrank , mpi_access ) ;
399 sts = mpi_access->cancel( source, MPITag, datatype, outcount ,
400 //sts = mpi_access->cancel( source, datatype, outcount ,
401 //RecvRequestId[lasttime] ,
403 debugStream << "test" << myrank << " TO CANCEL RequestId "
404 << RecvRequestId[lasttime]
405 << " tag " << mpi_access->recvMPITag( target )
406 << " cancelflag " << cancelflag << endl ;
407 chksts( sts , myrank , mpi_access ) ;
408 sts = mpi_access->IProbe( target , source, MPITag, datatype,
410 chksts( sts , myrank , mpi_access ) ;
413 if(MPI_ACCESS_VERBOSE) mpi_access->check() ;
416 int sendrequests[2*maxreq] ;
417 int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ;
418 if ( sendreqsize != 0 ) {
419 ostringstream strstream ;
420 strstream << "=========================================================" << endl
421 << "test" << myrank << " sendreqsize " << sendreqsize << " KO" << endl
422 << "=========================================================" << endl ;
423 debugStream << strstream.str() << endl ;
424 CPPUNIT_FAIL( strstream.str() ) ;
427 debugStream << "=========================================================" << endl
428 << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl
429 << "=========================================================" << endl ;
433 int recvrequests[2*maxreq] ;
434 int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ;
435 if ( recvreqsize != 0 ) {
436 ostringstream strstream ;
437 strstream << "=========================================================" << endl
438 << "test" << myrank << " recvreqsize " << recvreqsize << " KO" << endl
439 << "=========================================================" << endl ;
440 debugStream << strstream.str() << endl ;
441 CPPUNIT_FAIL( strstream.str() ) ;
444 debugStream << "=========================================================" << endl
445 << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl
446 << "=========================================================" << endl ;
451 for ( i = 0 ; i <= lasttime ; i++ ) {
452 debugStream << "test" << myrank << " " << i << ". RecvTimeMsg "
453 << aRecvTimeMsg[i].time << " recvbuf " << recvbuf[i] << endl ;
456 debugStream << "test_MPI_Access_Time_0 rank" << myrank << " --> mpi_access->barrier" << endl ;
457 mpi_access->barrier() ;
458 debugStream << "test_MPI_Access_Time_0 rank" << myrank << " <-- mpi_access->barrier" << endl ;
465 debugStream << "test" << myrank << " OK" << endl ;