Back to index

salome-kernel  6.5.0
testMPI2.cxx
Go to the documentation of this file.
00001 #include <iostream>
00002 #include <math.h>
00003 #include <mpi.h>
00004 #include <stdlib.h>
00005 #define TIMEOUT 20
00006 #define EPSILON 0.00000001
00007 
00008 int main(int argc, char**argv)
00009 {
00010   int *indg;
00011   double *vector, sum=0., norm, etalon;
00012   int rank, size, grank, gsize, rsize;
00013   int vsize=20, lvsize, rlvsize;
00014   int i, k1, k2, imin, imax, nb;
00015   int srv=0;
00016   MPI_Comm com, icom;
00017   MPI_Status status; 
00018   char   port_name     [MPI_MAX_PORT_NAME]; 
00019   char   port_name_clt [MPI_MAX_PORT_NAME]; 
00020   std::string service = "SERVICE";
00021   bool debug=false;
00022 
00023 #ifndef WITHOPENMPI
00024   std::cout << "This test only works with openmpi implementation" << std::endl;
00025   exit(1);
00026 #endif
00027 
00028   for(i=1;i<argc;i++){
00029     std::string sargv = argv[i];
00030     if(sargv.find("-debug")!=std::string::npos)
00031       debug = true;
00032     else if(sargv.find("-vsize")!=std::string::npos)
00033       vsize = atoi(argv[++i]);
00034   }
00035 
00036   MPI_Init( &argc, &argv );
00037 
00038   MPI_Comm_size( MPI_COMM_WORLD, &size );
00039   MPI_Comm_rank( MPI_COMM_WORLD, &rank );
00040 
00041   MPI_Barrier(MPI_COMM_WORLD);
00042 
00043   MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
00044   if(rank==0){
00045     MPI_Open_port(MPI_INFO_NULL, port_name); 
00046     if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )  {
00047       if(debug)
00048         std::cout << "[" << rank << "] I am client: I get the service " << service << " !" << std::endl;
00049       MPI_Close_port( port_name );
00050     } 
00051     else if ( MPI_Publish_name((char*)service.c_str(), MPI_INFO_NULL, port_name) == MPI_SUCCESS )  {
00052       if(debug)
00053         std::cout << "[" << rank << "] I am server: I've managed to publish the service " << service << " !" << std::endl;
00054       srv = 1;
00055     }      
00056     else if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )  {
00057       if(debug)
00058         std::cout << "[" << rank << "] I am client: I get the service " << service << " !" << std::endl;;
00059       MPI_Close_port( port_name );
00060     } 
00061     else{
00062       if(debug)
00063         std::cout << "[" << rank << "] ERROR!!!" << std::endl;
00064       MPI_Finalize(); 
00065       exit(1);
00066     }
00067   }
00068   else{
00069     i = 0;
00070     while ( i != TIMEOUT  ) { 
00071       sleep(1);
00072       if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )  {
00073         if(debug)
00074           std::cout << "[" << rank << "] I am client: I get the service " << service << " !" << std::endl;
00075         break;
00076       } 
00077       i++;
00078     }
00079     if ( i == TIMEOUT ) {
00080       if(debug)
00081         std::cout << "[" << rank << "] Waiting too long exiting !" << std::endl;
00082       MPI_Finalize(); 
00083       exit(1);
00084     }
00085   }
00086   MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
00087   MPI_Bcast(&srv,1,MPI_INT,0,MPI_COMM_WORLD);
00088   if ( srv )
00089     MPI_Comm_accept( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
00090   else
00091     MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
00092 
00093   MPI_Intercomm_merge(icom,!srv,&com);
00094 
00095   MPI_Comm_rank( com, &grank );
00096   MPI_Comm_size( com, &gsize );
00097 
00098   MPI_Barrier(com);
00099   lvsize = ((rank+1)*vsize) / size - (rank*vsize) / size;
00100   vector = (double*)malloc(lvsize*sizeof(double));
00101   indg = (int*)malloc(lvsize*sizeof(int));
00102   rsize = gsize - size;
00103 
00104   for(i=0;i<lvsize;i++){
00105     indg[i] = (rank*vsize)/size + i;
00106     if(srv){
00107       if(debug)
00108         vector[i] = indg[i];
00109       else
00110         vector[i] = 2. * sin( (rank*vsize)/size + i );
00111       sum += vector[i]*vector[i];
00112     }
00113   }
00114   MPI_Barrier(com);
00115   if(srv){
00116     MPI_Reduce(&sum,&norm,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
00117     if(rank==0){
00118       norm = sqrt(norm);
00119       if(debug)
00120         std::cout << "[" << grank << "] norm=" << norm << std::endl;
00121     }
00122   }
00123 
00124   for(i=0;i<rsize;i++){
00125     rlvsize = ((i+1)*vsize) / rsize - (i*vsize) / rsize;
00126     k1 = (i*vsize)/rsize;
00127     k2 = ((i+1)*vsize)/rsize -1;
00128 
00129     if( (k1 <= indg[lvsize-1]) && (k2 >= indg[0]) ){
00130       imin = k1;
00131       if( indg[0] > imin ) imin = indg[0];
00132       imax = k2;
00133       if( indg[lvsize-1] < imax) imax = indg[lvsize-1];
00134       if(srv){
00135         nb = imax - imin + 1;
00136         MPI_Send( &nb, 1, MPI_INT, i+size, 100, com );
00137         MPI_Send( vector+imin-indg[0], nb, MPI_DOUBLE, i+size, 200, com );
00138       }
00139       else{
00140         MPI_Recv( &nb, 1, MPI_INT, i, 100, com, &status );
00141         MPI_Recv( vector+imin-indg[0], nb, MPI_DOUBLE, i, 200, com, &status );
00142       }
00143     }
00144   }
00145 
00146   MPI_Barrier(com);
00147   if(!srv){
00148     sum = 0.;
00149     sleep(grank);
00150     for(i=0;i<lvsize;i++){
00151       if(debug)
00152         std::cout << "[" << rank << "] vector[" << i << "]=" << vector[i] << std::endl;
00153       sum += vector[i]*vector[i];
00154     }
00155     MPI_Reduce(&sum,&norm,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
00156     if(rank==0){
00157       norm = sqrt(norm);
00158       if(debug)
00159         std::cout << "[" << grank << "] norm=" << norm << std::endl;
00160     }
00161   }
00162 
00163   MPI_Barrier(com);
00164   if(srv){
00165     if(rank==0){
00166       MPI_Recv(&etalon, 1, MPI_DOUBLE,size,400,com, &status);
00167       MPI_Send(&norm,1,MPI_DOUBLE, size, 300, com);
00168     }
00169   }
00170   else if(rank==0){
00171     MPI_Send(&norm,1,MPI_DOUBLE, 0, 400, com);
00172     MPI_Recv(&etalon, 1, MPI_DOUBLE,0,300,com, &status);
00173   }
00174 
00175   MPI_Barrier(com);
00176   if(rank!=0) srv = 0;
00177 
00178   MPI_Comm_disconnect( &com ); 
00179   if ( srv ) {
00180     MPI_Unpublish_name((char*)service.c_str(), MPI_INFO_NULL, port_name); 
00181     MPI_Close_port( port_name ); 
00182   }
00183 
00184   free(indg);
00185   free(vector);
00186   MPI_Finalize();
00187 
00188   if(rank==0){
00189     if(fabs(norm-etalon)/norm < EPSILON ){
00190       if(debug)
00191         std::cout << "OK" << std::endl;
00192       exit(0);
00193     }
00194     else{
00195       if(debug)
00196         std::cout << "KO" << std::endl;
00197       exit(1);
00198     }
00199   }
00200 
00201 }