1 // Copyright (C) 2007-2015 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, or (at your option) any later version.
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
20 #include "MPI2Connector.hxx"
29 MPI2Connector::MPI2Connector()
31 MPI_Comm_size( MPI_COMM_WORLD, &_nb_proc );
32 MPI_Comm_rank( MPI_COMM_WORLD, &_num_proc );
35 MPI2Connector::~MPI2Connector()
39 MPI_Comm MPI2Connector::remoteMPI2Connect(const std::string& service)
42 char port_name[MPI_MAX_PORT_NAME];
43 char port_name_clt[MPI_MAX_PORT_NAME];
44 std::ostringstream msg;
47 if( service.size() == 0 )
49 msg << "[" << _num_proc << "] You have to give a service name !";
50 std::cerr << msg.str().c_str() << std::endl;
51 throw std::exception();
56 MPI_Barrier(MPI_COMM_WORLD);
58 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
61 /* rank 0 try to be a server. If service is already published, try to be a cient */
62 MPI_Open_port(MPI_INFO_NULL, port_name);
63 if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )
65 std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl;
66 MPI_Close_port( port_name );
68 else if ( MPI_Publish_name((char*)service.c_str(), MPI_INFO_NULL, port_name) == MPI_SUCCESS )
71 _port_name = port_name;
72 std::cerr << "[" << _num_proc << "] service " << service << " available at " << port_name << std::endl;
74 else if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )
76 std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl;
77 MPI_Close_port( port_name );
81 msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt;
82 std::cerr << msg.str().c_str() << std::endl;
83 throw std::exception();
89 /* Waiting rank 0 publish name and try to be a client */
90 while ( i != TIMEOUT )
93 if ( MPI_Lookup_name((char*)service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS )
95 std::cerr << "[" << _num_proc << "] I get the connection with " << service << " at " << port_name_clt << std::endl;
102 msg << "[" << _num_proc << "] Error on connection with " << service << " at " << port_name_clt;
103 std::cerr << msg.str().c_str() << std::endl;
104 throw std::exception();
107 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
109 /* If rank 0 is server, all processes call MPI_Comm_accept */
110 /* If rank 0 is not server, all processes call MPI_Comm_connect */
112 MPI_Bcast(&srv,1,MPI_INT,0,MPI_COMM_WORLD);
115 MPI_Comm_accept( port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
117 MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &icom );
119 /* create global communicator: servers have low index in global communicator*/
120 MPI_Intercomm_merge(icom,!_srv,&_gcom);
122 /* only rank 0 can be server for unpublish name */
123 if(_num_proc != 0) _srv = false;
129 void MPI2Connector::remoteMPI2Disconnect(const std::string& service)
131 std::ostringstream msg;
133 if( service.size() == 0 )
135 msg << "[" << _num_proc << "] You have to give a service name !";
136 std::cerr << msg.str().c_str() << std::endl;
137 throw std::exception();
140 MPI_Comm_disconnect( &_gcom );
144 char port_name[MPI_MAX_PORT_NAME];
145 strcpy(port_name,_port_name.c_str());
147 MPI_Unpublish_name((char*)service.c_str(), MPI_INFO_NULL, port_name);
148 std::cerr << "[" << _num_proc << "] " << service << ": close port " << _port_name << std::endl;
149 MPI_Close_port( port_name );