1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SALOME MPIContainer : implemenation of container based on MPI libraries
23 // File : MPIObject_i.cxx
26 #include "MPIObject_i.hxx"
27 #include "utilities.h"
31 MPIObject_i::MPIObject_i()
33 MPI_Comm_size( MPI_COMM_WORLD, &_nbproc );
34 MPI_Comm_rank( MPI_COMM_WORLD, &_numproc );
38 MPIObject_i::MPIObject_i(int nbproc, int numproc)
45 MPIObject_i::~MPIObject_i()
47 if(_tior) delete _tior;
50 Engines::IORTab* MPIObject_i::tior()
52 Engines::IORTab_var tior = new Engines::IORTab;
53 tior->length(_tior->length());
54 for(unsigned int ip=0;ip<tior->length();ip++)
55 tior[ip] = (*_tior)[ip];
59 void MPIObject_i::tior(const Engines::IORTab& ior)
61 _tior = new Engines::IORTab;
62 _tior->length(ior.length());
63 for(unsigned int ip=0;ip<ior.length();ip++)
64 (*_tior)[ip] = ior[ip];
67 void MPIObject_i::BCastIOR(CORBA::ORB_ptr orb, Engines::MPIObject_ptr pobj,
68 bool amiCont) throw(POException)
72 MPI_Status status; /* status de reception de message MPI */
76 //Allocation du tableau des IOR
77 Engines::IORTab_var iort = new Engines::IORTab;
78 iort->length(_nbproc);
82 // Process 0 recupere les ior de l'object sur les autres process
83 for(ip=1;ip<_nbproc;ip++){
84 err = MPI_Recv(&n,1,MPI_INT,ip,ip,MPI_COMM_WORLD,&status);
86 MESSAGE("[" << _numproc << "] MPI_RECV error");
89 // Allocation de la chaine de longueur n
91 err = MPI_Recv(ior,n,MPI_CHAR,ip,2*ip,MPI_COMM_WORLD,&status);
93 MESSAGE("[" << _numproc << "] MPI_RECV error");
96 iort[ip] = orb->string_to_object(ior);
98 if(CORBA::is_nil(iort[ip]))
99 throw POException(ip,"MPI Component not loaded");
101 // On donne le tableau des ior a l'objet Corba du process 0
103 tior(*(iort._retn()));
105 pobj->tior(*(iort._retn()));
108 // Conversion IOR vers string
109 ior = orb->object_to_string(pobj);
111 // On envoie l'IOR au process 0
112 err = MPI_Send(&n,1,MPI_INT,0,_numproc,MPI_COMM_WORLD);
114 MESSAGE("[" << _numproc << "] MPI_SEND error");
117 err = MPI_Send(ior,n,MPI_CHAR,0,2*_numproc,MPI_COMM_WORLD);
119 MESSAGE("[" << _numproc << "] MPI_SEND error");
122 CORBA::string_free(ior);
128 MPI_Comm MPIObject_i::remoteMPI2Connect(string service) throw(POException)
132 char port_name_clt[MPI_MAX_PORT_NAME];
137 MPI_Barrier(MPI_COMM_WORLD);
139 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
141 /* rank 0 try to be a server. If service is already published, try to be a cient */
142 MPI_Open_port(MPI_INFO_NULL, _port_name);
143 if ( MPI_Publish_name((char*)_service.c_str(), MPI_INFO_NULL, _port_name) == MPI_SUCCESS ) {
145 MESSAGE("[" << _numproc << "] service " << _service << " available at " << _port_name << "\n");
147 else if ( MPI_Lookup_name((char*)_service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS ){
148 MESSAGE("[" << _numproc << "] I get the connection with " << _service << " at " << port_name_clt << "!\n");
149 MPI_Close_port( _port_name );
152 /* Throw exception */
153 MESSAGE("[" << _numproc << "] Error on connection with " << _service << " at " << port_name_clt << "!\n");
154 throw POException(_numproc,"Error on connection with " + _service + " at " + port_name_clt);
159 /* Waiting rank 0 publish name and try to be a client */
160 while ( i != TIMEOUT ) {
162 if ( MPI_Lookup_name((char*)_service.c_str(), MPI_INFO_NULL, port_name_clt) == MPI_SUCCESS ){
163 MESSAGE("[" << _numproc << "] I get the connection with " << _service << " at " << port_name_clt << "!\n");
169 /* Throw exception */
170 MESSAGE("[" << _numproc << "] Error on connection with " << _service << " at " << port_name_clt << "!\n");
171 throw POException(_numproc,"Error on connection with " + _service + " at " + port_name_clt);
174 MPI_Errhandler_set(MPI_COMM_WORLD, MPI_ERRORS_ARE_FATAL);
176 /* If rank 0 is server, all processes call MPI_Comm_accept */
177 /* If rank 0 is not server, all processes call MPI_Comm_connect */
178 MPI_Bcast(&_srv,1,MPI_INT,0,MPI_COMM_WORLD);
180 MPI_Comm_accept( _port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &gcom );
182 MPI_Comm_connect(port_name_clt, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &gcom );
184 /* only rank 0 can be server for unpublish name */
185 if(_numproc != 0) _srv = 0;
191 void MPIObject_i::remoteMPI2Disconnect(MPI_Comm gcom)
193 MPI_Comm_disconnect( &gcom );
195 MPI_Unpublish_name((char*)_service.c_str(), MPI_INFO_NULL, _port_name);
196 MESSAGE("[" << _numproc << "] " << _service << ": close port " << _port_name << "\n");
197 MPI_Close_port( _port_name );