Salome HOME
Update copyrights 2014.
[modules/med.git] / src / ParaMEDMEMTest / test_MPI_Access_Cancel.cxx
1 // Copyright (C) 2007-2014  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 <time.h>
21 #include <string>
22 #include <vector>
23 #include <map>
24 #include <iostream>
25 #include <mpi.h>
26
27 #ifndef WIN32
28 #include <unistd.h>
29 #endif
30
31 #include "MPIAccessTest.hxx"
32 #include <cppunit/TestAssert.h>
33
34 //#include "CommInterface.hxx"
35 //#include "ProcessorGroup.hxx"
36 //#include "MPIProcessorGroup.hxx"
37 #include "MPIAccess.hxx"
38
39 // use this define to enable lines, execution of which leads to Segmentation Fault
40 #define ENABLE_FAULTS
41
42 // use this define to enable CPPUNIT asserts and fails, showing bugs
43 #define ENABLE_FORCED_FAILURES
44
45 using namespace std;
46 using namespace ParaMEDMEM;
47
48 void MPIAccessTest::test_MPI_Access_Cancel() {
49
50   cout << "test_MPI_Access_Cancel" << endl ;
51
52 //  MPI_Init(&argc, &argv) ; 
53
54   int size ;
55   int myrank ;
56   MPI_Comm_size(MPI_COMM_WORLD,&size) ;
57   MPI_Comm_rank(MPI_COMM_WORLD,&myrank) ;
58
59   if ( size < 2 ) {
60     ostringstream strstream ;
61     strstream << "test_MPI_Access_Cancel must be runned with 2 procs" << endl ;
62     cout << strstream.str() << endl ;
63     CPPUNIT_FAIL( strstream.str() ) ;
64   }
65
66   cout << "test_MPI_Access_Cancel" << myrank << endl ;
67
68   ParaMEDMEM::CommInterface interface ;
69
70   ParaMEDMEM::MPIProcessorGroup* group = new ParaMEDMEM::MPIProcessorGroup(interface) ;
71
72   ParaMEDMEM::MPIAccess mpi_access( group ) ;
73
74   if ( myrank >= 2 ) {
75     mpi_access.barrier() ;
76     delete group ;
77     return ;
78   }
79
80   int target = 1 - myrank ;
81   int intsendbuf[5] ;
82   double doublesendbuf[10] ;
83   int RequestId[10] ;
84   int sts ;
85   int i , j ;
86   for ( j = 0 ; j < 3 ; j++ ) {
87      for ( i = 0 ; i < 10 ; i++ ) {
88         cout << "test" << myrank << " ============================ i " << i
89              << "============================" << endl ;
90         if ( myrank == 0 ) {
91           if ( i < 5 ) {
92             intsendbuf[i] = i ;
93             sts = mpi_access.ISend(&intsendbuf[i],1,MPI_INT,target, RequestId[i]) ;
94             cout << "test" << myrank << " Send MPI_INT RequestId " << RequestId[i]
95                  << endl ;
96           }
97           else {
98             doublesendbuf[i] = i ;
99             sts = mpi_access.ISend(&doublesendbuf[i],1,MPI_DOUBLE,target,
100                                    RequestId[i]) ;
101             cout << "test" << myrank << " Send MPI_DOUBLE RequestId " << RequestId[i]
102                  << endl ;
103           }
104         }
105         else {
106           int flag = false ;
107           while ( !flag ) {
108                int source, tag, outcount ;
109                MPI_Datatype datatype ;
110                sts = mpi_access.IProbe(target, source, tag, datatype, outcount,
111                                        flag ) ;
112                if ( flag ) {
113                  cout << "test" << myrank << " " << i << " IProbe target " << target
114                       << " source " << source << " tag " << tag
115                       << " outcount " << outcount << " flag " << flag << endl ;
116                }
117                else {
118                  cout << "test" << myrank << " flag " << flag << endl ;
119                  sleep( 1 ) ;
120                }
121                if ( flag ) {
122                  int recvbuf ;
123                  sts = mpi_access.IRecv(&recvbuf,outcount,MPI_INT,source,
124                                         RequestId[i] ) ;
125                  if ( datatype == MPI_INT ) {
126                    int source, tag, error, outcount ;
127                    mpi_access.wait( RequestId[i] ) ;
128                    mpi_access.status( RequestId[i], source, tag, error, outcount,
129                                       true ) ;
130                    if ( (outcount != 1) | (recvbuf != i) ) {
131                      ostringstream strstream ;
132                      strstream << "======================================================"
133                                << endl << "test" << myrank << " outcount " << outcount
134                                << " recvbuf " << recvbuf << " KO" << endl
135                                << "======================================================"
136                                << endl ;
137                      cout << strstream.str() << endl ;
138                      CPPUNIT_FAIL( strstream.str() ) ;
139                    }
140                    cout << "========================================================"
141                         << endl << "test" << myrank << " outcount " << outcount
142                         << " recvbuf " << recvbuf << " OK" << endl
143                         << "========================================================"
144                         << endl ;
145                  }
146                }
147           }
148         }
149         char msgerr[MPI_MAX_ERROR_STRING] ;
150         int lenerr ;
151         mpi_access.errorString(sts, msgerr, &lenerr) ;
152         cout << "test" << myrank << " lenerr " << lenerr << " "
153              << msgerr << endl ;
154         if ( sts != MPI_SUCCESS ) {
155           ostringstream strstream ;
156           strstream << "==========================================================="
157                     << endl << "test" << myrank << " KO"
158                     << "==========================================================="
159                     << endl ;
160           cout << strstream.str() << endl ;
161           CPPUNIT_FAIL( strstream.str() ) ;
162         }
163         mpi_access.check() ;
164      }
165
166      if ( myrank != 0 ) {
167        int iprobe ;
168        for ( iprobe = 5 ; iprobe < 10 ; iprobe++ ) {
169           cout << "test" << myrank << " ============================ iprobe "
170                << iprobe << "============================" << endl ;
171           int source, tag, outcount ;
172           MPI_Datatype datatype ;
173           int probeflag = false ;
174           while ( !probeflag ) {
175                sts = mpi_access.IProbe( target, source, tag, datatype, outcount,
176                                         probeflag ) ;
177                char msgerr[MPI_MAX_ERROR_STRING] ;
178                int lenerr ;
179                mpi_access.errorString(sts, msgerr, &lenerr) ;
180                cout << "test" << myrank << " IProbe iprobe " << iprobe
181                     << " target " << target << " probeflag " << probeflag
182                     << " tag " << tag << " outcount " << outcount << " datatype "
183                     << datatype << " lenerr " << lenerr << " " << msgerr << endl ;
184                if ( sts != MPI_SUCCESS ) {
185                  ostringstream strstream ;
186                  strstream << "=========================================================="
187                            << endl << "test" << myrank << " IProbe KO iprobe " << iprobe
188                            << endl
189                            << "=========================================================="
190                            << endl ;
191                  cout << strstream.str() << endl ;
192                  CPPUNIT_FAIL( strstream.str() ) ;
193                }
194                if ( !probeflag ) {
195                  //cout << "========================================================"
196                  //     << endl << "test" << myrank << " IProbe KO(OK) iprobe " << iprobe
197                  //     << " probeflag " << probeflag << endl
198                  //     << "========================================================"
199                  //     << endl ;
200                }
201                else {
202                  cout << "test" << myrank << " " << iprobe << " IProbe target "
203                       << target << " source " << source << " tag " << tag
204                       << " outcount " << outcount << " probeflag " << probeflag
205                       << endl ;
206                  if ( datatype != MPI_DOUBLE ) {
207                    ostringstream strstream ;
208                    strstream << "========================================================"
209                              << endl << "test" << myrank << " MPI_DOUBLE KO" << endl
210                              << "========================================================"
211                              << endl ;
212                    cout << strstream.str() << endl ;
213                    CPPUNIT_FAIL( strstream.str() ) ;
214                  }
215                  else {
216                    int flag ;
217                    sts = mpi_access.cancel( source, tag, datatype, outcount, flag ) ;
218                    if ( sts != MPI_SUCCESS || !flag ) {
219                      mpi_access.errorString(sts, msgerr, &lenerr) ;
220                      cout << "======================================================"
221                           << endl << "test" << myrank << " lenerr " << lenerr << " "
222                           << msgerr << endl << "test" << myrank
223                           << " Cancel PendingIrecv KO flag " << flag << " iprobe "
224                           << iprobe << " Irecv completed" << endl
225                           << "======================================================"
226                           << endl ;
227                      //return 1 ;
228                    }
229                    else {
230                      cout << "======================================================"
231                           << endl << "test" << myrank
232                           << " Cancel PendingIrecv OK RequestId " << " flag "
233                           << flag << " iprobe " << iprobe << endl
234                           << "======================================================"
235                           << endl ;
236                    }
237                  }
238                  int Reqtarget, Reqtag, Reqerror, Reqoutcount ;
239                  mpi_access.status( RequestId[iprobe], Reqtarget, Reqtag, Reqerror,
240                                     Reqoutcount, true ) ;
241                  cout << "test" << myrank << " Status Reqtarget "<< Reqtarget
242                       << " Reqtag " << Reqtag << " Reqoutcount " << Reqoutcount
243                       << endl ;
244                  int Reqflag ;
245                  sts = mpi_access.cancel( RequestId[iprobe] , Reqflag ) ;
246                  cout << "test" << myrank << " " << iprobe
247                       << " Cancel Irecv done Reqtarget " << Reqtarget
248                       << " Reqtag " << Reqtag << " Reqoutcount " << Reqoutcount
249                       << " Reqflag " << Reqflag << endl ;
250                  if ( sts != MPI_SUCCESS || !Reqflag ) {
251                    mpi_access.errorString(sts, msgerr, &lenerr) ;
252                    ostringstream strstream ;
253                    strstream << "========================================================"
254                              << endl << "test" << myrank << " lenerr " << lenerr << " "
255                              << msgerr << endl << "test" << myrank
256                              << " Cancel Irecv KO Reqflag " << Reqflag << " iprobe "
257                              << iprobe << endl
258                              << "========================================================"
259                              << endl ;
260                    cout << strstream.str() << endl ;
261                    CPPUNIT_FAIL( strstream.str() ) ;
262                  }
263                  else {
264                    cout << "========================================================"
265                         << endl << "test" << myrank
266                         << " Cancel Irecv OK RequestId " << RequestId[iprobe]
267                         << " Reqflag " << Reqflag << " iprobe " << iprobe << endl
268                         << "========================================================"
269                         << endl ;
270                    probeflag = Reqflag ;
271                  }
272                }
273           }
274        }
275      }
276      mpi_access.waitAll(10,RequestId) ;
277      mpi_access.deleteRequests(10,RequestId) ;
278   }
279
280   int source, tag, outcount, flag ;
281   MPI_Datatype datatype ;
282   sts = mpi_access.IProbe(target, source, tag, datatype, outcount, flag ) ;
283   char msgerr[MPI_MAX_ERROR_STRING] ;
284   int lenerr ;
285   mpi_access.errorString(sts, msgerr, &lenerr) ;
286   cout << "test" << myrank << " lenerr " << lenerr << " "
287        << msgerr << endl ;
288   if ( sts != MPI_SUCCESS || flag ) {
289     ostringstream strstream ;
290     strstream << "==========================================================="
291               << endl << "test" << myrank << " IProbe KO flag " << flag
292               << " remaining unread/cancelled message :" << endl
293               << " source " << source << " tag " << tag << endl
294               << "==========================================================="
295               << endl ;
296     cout << strstream.str() << endl ;
297     CPPUNIT_FAIL( strstream.str() ) ;
298   }
299
300   mpi_access.testAll(10,RequestId,flag) ;
301   mpi_access.waitAll(10,RequestId) ;
302   mpi_access.deleteRequests(10,RequestId) ;
303   mpi_access.testAll(10,RequestId,flag) ;
304   if ( !flag ) {
305     ostringstream strstream ;
306     strstream << "test" << myrank << " flag " << flag << " KO" << endl ;
307     cout << strstream.str() << endl ;
308     CPPUNIT_FAIL( strstream.str() ) ;
309   }
310   mpi_access.check() ;
311
312   mpi_access.barrier() ;
313
314   delete group ;
315
316 //  MPI_Finalize();
317
318   cout << "test" << myrank << " OK" << endl ;
319
320   return ;
321 }
322
323
324
325