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