Salome HOME
Try to kill Salome application when a YACS Launcher job is killed
[modules/kernel.git] / src / MPIContainer / testMPI2.cxx
1 #include <iostream>
2 #include <math.h>
3 #include <mpi.h>
4 #include <stdlib.h>
5 #define TIMEOUT 20
6 #define EPSILON 0.00000001
7
8 int main(int argc, char**argv)
9 {
10   int *indg;
11   double *vector, sum=0., norm, etalon;
12   int rank, size, grank, gsize, rsize;
13   int vsize=20, lvsize, rlvsize;
14   int i, k1, k2, imin, imax, nb;
15   int srv=0;
16   MPI_Comm com, icom;
17   MPI_Status status; 
18   char   port_name     [MPI_MAX_PORT_NAME]; 
19   char   port_name_clt [MPI_MAX_PORT_NAME]; 
20   std::string service = "SERVICE";
21   bool debug=false;
22
23 #ifndef WITHOPENMPI
24   std::cout << "This test only works with openmpi implementation" << std::endl;
25   exit(1);
26 #endif
27
28   for(i=1;i<argc;i++){
29     std::string sargv = argv[i];
30     if(sargv.find("-debug")!=std::string::npos)
31       debug = true;
32     else if(sargv.find("-vsize")!=std::string::npos)
33       vsize = atoi(argv[++i]);
34   }
35
36   MPI_Init( &argc, &argv );
37
38   MPI_Comm_size( MPI_COMM_WORLD, &size );
39   MPI_Comm_rank( MPI_COMM_WORLD, &rank );
40
41   MPI_Barrier(MPI_COMM_WORLD);
42
43   MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
44   if(rank==0){
45     MPI_Open_port(MPI_INFO_NULL, port_name); 
46     if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )  {
47       if(debug)
48         std::cout << "[" << rank << "] I am client: I get the service " << service << " !" << std::endl;
49       MPI_Close_port( port_name );
50     } 
51     else if ( MPI_Publish_name((char*)service.c_str(), MPI_INFO_NULL, port_name) == MPI_SUCCESS )  {
52       if(debug)
53         std::cout << "[" << rank << "] I am server: I've managed to publish the service " << service << " !" << std::endl;
54       srv = 1;
55     }      
56     else if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )  {
57       if(debug)
58         std::cout << "[" << rank << "] I am client: I get the service " << service << " !" << std::endl;;
59       MPI_Close_port( port_name );
60     } 
61     else{
62       if(debug)
63         std::cout << "[" << rank << "] ERROR!!!" << std::endl;
64       MPI_Finalize(); 
65       exit(1);
66     }
67   }
68   else{
69     i = 0;
70     while ( i != TIMEOUT  ) { 
71       sleep(1);
72       if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )  {
73         if(debug)
74           std::cout << "[" << rank << "] I am client: I get the service " << service << " !" << std::endl;
75         break;
76       } 
77       i++;
78     }
79     if ( i == TIMEOUT ) {
80       if(debug)
81         std::cout << "[" << rank << "] Waiting too long exiting !" << std::endl;
82       MPI_Finalize(); 
83       exit(1);
84     }
85   }
86   MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
87   MPI_Bcast(&srv,1,MPI_INT,0,MPI_COMM_WORLD);
88   if ( srv )
89     MPI_Comm_accept( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
90   else
91     MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
92
93   MPI_Intercomm_merge(icom,!srv,&com);
94
95   MPI_Comm_rank( com, &grank );
96   MPI_Comm_size( com, &gsize );
97
98   MPI_Barrier(com);
99   lvsize = ((rank+1)*vsize) / size - (rank*vsize) / size;
100   vector = (double*)malloc(lvsize*sizeof(double));
101   indg = (int*)malloc(lvsize*sizeof(int));
102   rsize = gsize - size;
103
104   for(i=0;i<lvsize;i++){
105     indg[i] = (rank*vsize)/size + i;
106     if(srv){
107       if(debug)
108         vector[i] = indg[i];
109       else
110         vector[i] = 2. * sin( (rank*vsize)/size + i );
111       sum += vector[i]*vector[i];
112     }
113   }
114   MPI_Barrier(com);
115   if(srv){
116     MPI_Reduce(&sum,&norm,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
117     if(rank==0){
118       norm = sqrt(norm);
119       if(debug)
120         std::cout << "[" << grank << "] norm=" << norm << std::endl;
121     }
122   }
123
124   for(i=0;i<rsize;i++){
125     rlvsize = ((i+1)*vsize) / rsize - (i*vsize) / rsize;
126     k1 = (i*vsize)/rsize;
127     k2 = ((i+1)*vsize)/rsize -1;
128
129     if( (k1 <= indg[lvsize-1]) && (k2 >= indg[0]) ){
130       imin = k1;
131       if( indg[0] > imin ) imin = indg[0];
132       imax = k2;
133       if( indg[lvsize-1] < imax) imax = indg[lvsize-1];
134       if(srv){
135         nb = imax - imin + 1;
136         MPI_Send( &nb, 1, MPI_INT, i+size, 100, com );
137         MPI_Send( vector+imin-indg[0], nb, MPI_DOUBLE, i+size, 200, com );
138       }
139       else{
140         MPI_Recv( &nb, 1, MPI_INT, i, 100, com, &status );
141         MPI_Recv( vector+imin-indg[0], nb, MPI_DOUBLE, i, 200, com, &status );
142       }
143     }
144   }
145
146   MPI_Barrier(com);
147   if(!srv){
148     sum = 0.;
149     sleep(grank);
150     for(i=0;i<lvsize;i++){
151       if(debug)
152         std::cout << "[" << rank << "] vector[" << i << "]=" << vector[i] << std::endl;
153       sum += vector[i]*vector[i];
154     }
155     MPI_Reduce(&sum,&norm,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
156     if(rank==0){
157       norm = sqrt(norm);
158       if(debug)
159         std::cout << "[" << grank << "] norm=" << norm << std::endl;
160     }
161   }
162
163   MPI_Barrier(com);
164   if(srv){
165     if(rank==0){
166       MPI_Recv(&etalon, 1, MPI_DOUBLE,size,400,com, &status);
167       MPI_Send(&norm,1,MPI_DOUBLE, size, 300, com);
168     }
169   }
170   else if(rank==0){
171     MPI_Send(&norm,1,MPI_DOUBLE, 0, 400, com);
172     MPI_Recv(&etalon, 1, MPI_DOUBLE,0,300,com, &status);
173   }
174
175   MPI_Barrier(com);
176   if(rank!=0) srv = 0;
177
178   MPI_Comm_disconnect( &com ); 
179   if ( srv ) {
180     MPI_Unpublish_name((char*)service.c_str(), MPI_INFO_NULL, port_name); 
181     MPI_Close_port( port_name ); 
182   }
183
184   free(indg);
185   free(vector);
186   MPI_Finalize();
187
188   if(rank==0){
189     if(fabs(norm-etalon)/norm < EPSILON ){
190       if(debug)
191         std::cout << "OK" << std::endl;
192       exit(0);
193     }
194     else{
195       if(debug)
196         std::cout << "KO" << std::endl;
197       exit(1);
198     }
199   }
200
201 }