1 // Copyright (C) 2007-2008 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.
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
25 #include "MPIAccessTest.hxx"
26 #include <cppunit/TestAssert.h>
28 //#include "CommInterface.hxx"
29 //#include "ProcessorGroup.hxx"
30 //#include "MPIProcessorGroup.hxx"
31 #include "MPIAccess.hxx"
33 // use this define to enable lines, execution of which leads to Segmentation Fault
36 // use this define to enable CPPUNIT asserts and fails, showing bugs
37 #define ENABLE_FORCED_FAILURES
40 using namespace ParaMEDMEM;
42 void chksts( int sts , int myrank , ParaMEDMEM::MPIAccess * mpi_access ) {
43 char msgerr[MPI_MAX_ERROR_STRING] ;
45 if ( sts != MPI_SUCCESS ) {
46 mpi_access->errorString(sts, msgerr, &lenerr) ;
47 cout << "test" << myrank << " lenerr " << lenerr << " "
49 ostringstream strstream ;
50 strstream << "==========================================================="
51 << "test" << myrank << " KO"
52 << "==========================================================="
54 cout << strstream.str() << endl ;
55 CPPUNIT_FAIL( strstream.str() ) ;
60 void MPIAccessTest::test_MPI_Access_Time_0() {
62 cout << "test_MPI_Access_Time_0" << endl ;
64 // MPI_Init(&argc, &argv) ;
68 MPI_Comm_size(MPI_COMM_WORLD,&size) ;
69 MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ;
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() ) ;
84 double dt[2] = {2., 1.} ;
85 double maxt = maxreq/dt[myrank] ;
87 cout << "test_MPI_Access_Time_0 rank" << myrank << endl ;
89 ParaMEDMEM::CommInterface interface ;
91 ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ;
93 ParaMEDMEM::MPIAccess * mpi_access = new ParaMEDMEM::MPIAccess( group ) ;
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 ;
104 cout << "test_MPI_Access_Time" << myrank << " OK" << endl ;
108 int target = 1 - myrank ;
109 int SendTimeRequestId[maxreq] ;
110 int RecvTimeRequestId[maxreq] ;
111 int SendRequestId[maxreq] ;
112 int RecvRequestId[maxreq] ;
114 int sendbuf[maxreq] ;
115 int recvbuf[maxreq] ;
116 ParaMEDMEM::TimeMessage aSendTimeMsg[maxreq] ;
118 ParaMEDMEM::TimeMessage RecvTimeMessages[maxreq+1] ;
119 ParaMEDMEM::TimeMessage *aRecvTimeMsg = &RecvTimeMessages[1] ;
120 // mpi_access->Trace() ;
122 for ( t = 0 ; t < maxt ; t = t+dt[myrank] ) {
123 cout << "test" << myrank << " ==========================TIME " << t
124 << " ==========================" << endl ;
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 ;
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 ) ;
145 int sendrequests[2*maxreq] ;
146 int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq ,
149 for ( j = 0 ; j < sendreqsize ; j++ ) {
150 sts = mpi_access->test( sendrequests[j] , flag ) ;
151 chksts( sts , myrank , mpi_access ) ;
153 mpi_access->deleteRequest( sendrequests[j] ) ;
154 cout << "test" << myrank << " " << j << ". " << sendrequests[j]
155 << " sendrequest deleted" << endl ;
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] )
171 << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] ) << endl ;
172 chksts( sts , myrank , mpi_access ) ;
175 cout << "test" << myrank << " t # 0 lasttime " << lasttime << endl ;
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 << "==========================================================="
188 cout << strstream.str() << endl ;
189 CPPUNIT_FAIL( strstream.str() ) ;
192 cout << "==========================================================="
193 << endl << "test" << myrank << " t " << t << " > "
194 << "aRecvTimeMsg[ " << lasttime << "-1 ].time "
195 << aRecvTimeMsg[lasttime-1].time << " OK" << endl
196 << "==========================================================="
199 //outtime = ((aRecvTimeMsg[lasttime].time +
200 // aRecvTimeMsg[lasttime].deltatime) >=
201 // aRecvTimeMsg[lasttime].maxtime) ;
202 outtime = aRecvTimeMsg[lasttime].deltatime == 0 ;
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 ) {
212 cout << "test" << myrank << " while outtime( " << outtime << " && t " << t
213 << " > aRecvTimeMsg[ " << lasttime << " ] "
214 << aRecvTimeMsg[lasttime].time << " )" << endl ;
215 while ( !outtime && (t > aRecvTimeMsg[lasttime].time) ) {
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] ;
228 mpi_access->deleteRequest( RecvTimeRequestId[lasttime] ) ;
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 ) {
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,
246 chksts( sts , myrank , mpi_access ) ;
247 // Cancel DataMessages jusqu'a un TimeMessage
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] ,
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,
261 chksts( sts , myrank , mpi_access ) ;
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] ,
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 ) ;
283 cout << "test" << myrank << " Recv target " << target
284 << " lasttime " << lasttime
285 << " lasttime-1 " << aRecvTimeMsg[lasttime-1]
286 << " lasttime " << aRecvTimeMsg[lasttime]
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 )
294 chksts( sts , myrank , mpi_access ) ;
296 //outtime = ((aRecvTimeMsg[lasttime].time +
297 // aRecvTimeMsg[lasttime].deltatime) >=
298 // aRecvTimeMsg[lasttime].maxtime) ;
299 outtime = aRecvTimeMsg[lasttime].deltatime == 0 ;
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] )
309 << mpi_access->MPICompleted( RecvTimeRequestId[lasttime+1] )
311 chksts( sts , myrank , mpi_access ) ;
313 else if ( t <= aRecvTimeMsg[lasttime].time ) {
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]
332 << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl
333 << "==========================================================="
335 cout << strstream.str() << endl ;
336 CPPUNIT_FAIL( strstream.str() ) ;
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]
348 << RecvRequestId[lasttime-1] << " " << RecvRequestId[lasttime] << endl
349 << "==========================================================="
354 chksts( sts , myrank , mpi_access ) ;
358 cout << "test" << myrank << " Barrier :" << endl ;
359 mpi_access->barrier() ;
361 mpi_access->check() ;
366 cout << "test" << myrank << " CheckFinalSent :" << endl ;
367 int sendrequests[2*maxreq] ;
368 int sendreqsize = mpi_access->sendRequestIds( target , 2*maxreq , sendrequests ) ;
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"
379 cout << "test" << myrank << " CheckFinalRecv :" << endl ;
380 int recvrequests[2*maxreq] ;
381 int recvreqsize = mpi_access->recvRequestIds( target , 2*maxreq , recvrequests ) ;
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 ;
391 int source, MPITag, outcount , flag ;
392 MPI_Datatype datatype ;
393 sts = mpi_access->IProbe( target , source, MPITag, datatype,
395 chksts( sts , myrank , mpi_access ) ;
397 sts = mpi_access->cancel( source, MPITag, datatype, outcount ,
398 //sts = mpi_access->cancel( source, datatype, outcount ,
399 //RecvRequestId[lasttime] ,
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,
408 chksts( sts , myrank , mpi_access ) ;
411 mpi_access->check() ;
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() ) ;
425 cout << "=========================================================" << endl
426 << "test" << myrank << " sendreqsize " << sendreqsize << " OK" << endl
427 << "=========================================================" << endl ;
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() ) ;
442 cout << "=========================================================" << endl
443 << "test" << myrank << " recvreqsize " << recvreqsize << " OK" << endl
444 << "=========================================================" << endl ;
449 for ( i = 0 ; i <= lasttime ; i++ ) {
450 cout << "test" << myrank << " " << i << ". RecvTimeMsg "
451 << aRecvTimeMsg[i].time << " recvbuf " << recvbuf[i] << endl ;
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 ;
463 cout << "test" << myrank << " OK" << endl ;