166 lines
3.9 KiB
C++
166 lines
3.9 KiB
C++
/*
|
|
(c) Thales group, 2012
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation;
|
|
version 2 of the License.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Contact: http://eodev.sourceforge.net
|
|
|
|
Authors:
|
|
Benjamin Bouvier <benjamin.bouvier@gmail.com>
|
|
*/
|
|
# include "implMpi.h"
|
|
|
|
namespace mpi
|
|
{
|
|
const int any_source = MPI_ANY_SOURCE;
|
|
const int any_tag = MPI_ANY_TAG;
|
|
|
|
environment::environment(int argc, char**argv)
|
|
{
|
|
MPI_Init(&argc, &argv);
|
|
}
|
|
|
|
environment::~environment()
|
|
{
|
|
MPI_Finalize();
|
|
}
|
|
|
|
status::status( const MPI_Status & s )
|
|
{
|
|
_source = s.MPI_SOURCE;
|
|
_tag = s.MPI_TAG;
|
|
_error = s.MPI_ERROR;
|
|
}
|
|
|
|
communicator::communicator( )
|
|
{
|
|
_rank = -1;
|
|
_size = -1;
|
|
|
|
_buf = 0;
|
|
_bufsize = -1;
|
|
}
|
|
|
|
communicator::~communicator()
|
|
{
|
|
if( _buf )
|
|
{
|
|
delete _buf;
|
|
_buf = 0;
|
|
}
|
|
}
|
|
|
|
int communicator::rank()
|
|
{
|
|
if ( _rank == -1 )
|
|
{
|
|
MPI_Comm_rank( MPI_COMM_WORLD, &_rank );
|
|
}
|
|
return _rank;
|
|
}
|
|
|
|
int communicator::size()
|
|
{
|
|
if ( _size == -1 )
|
|
{
|
|
MPI_Comm_size( MPI_COMM_WORLD, &_size );
|
|
}
|
|
return _size;
|
|
}
|
|
|
|
/*
|
|
* SEND / RECV INT
|
|
*/
|
|
void communicator::send( int dest, int tag, int n )
|
|
{
|
|
MPI_Send( &n, 1, MPI_INT, dest, tag, MPI_COMM_WORLD );
|
|
}
|
|
|
|
void communicator::recv( int src, int tag, int& n )
|
|
{
|
|
MPI_Status stat;
|
|
MPI_Recv( &n, 1, MPI_INT, src, tag, MPI_COMM_WORLD , &stat );
|
|
}
|
|
|
|
/*
|
|
* SEND / RECV STRING
|
|
*/
|
|
void communicator::send( int dest, int tag, const std::string& str )
|
|
{
|
|
int size = str.size() + 1;
|
|
send( dest, tag, size );
|
|
MPI_Send( (char*)str.c_str(), size, MPI_CHAR, dest, tag, MPI_COMM_WORLD);
|
|
}
|
|
|
|
void communicator::recv( int src, int tag, std::string& str )
|
|
{
|
|
int size = -1;
|
|
MPI_Status stat;
|
|
recv( src, tag, size );
|
|
|
|
if( _buf == 0 )
|
|
{
|
|
_buf = new char[ size ];
|
|
_bufsize = size;
|
|
} else if( _bufsize < size )
|
|
{
|
|
delete [] _buf;
|
|
_buf = new char[ size ];
|
|
_bufsize = size;
|
|
}
|
|
MPI_Recv( _buf, size, MPI_CHAR, src, tag, MPI_COMM_WORLD, &stat );
|
|
str.assign( _buf );
|
|
}
|
|
|
|
/*
|
|
* SEND / RECV Objects
|
|
*/
|
|
void communicator::send( int dest, int tag, const eoserial::Persistent & persistent )
|
|
{
|
|
eoserial::Object* obj = persistent.pack();
|
|
std::stringstream ss;
|
|
obj->print( ss );
|
|
delete obj;
|
|
send( dest, tag, ss.str() );
|
|
}
|
|
|
|
void communicator::recv( int src, int tag, eoserial::Persistent & persistent )
|
|
{
|
|
std::string asText;
|
|
recv( src, tag, asText );
|
|
eoserial::Object* obj = eoserial::Parser::parse( asText );
|
|
persistent.unpack( obj );
|
|
delete obj;
|
|
}
|
|
|
|
/*
|
|
* Other methods
|
|
*/
|
|
status communicator::probe( int src, int tag )
|
|
{
|
|
MPI_Status stat;
|
|
MPI_Probe( src, tag, MPI_COMM_WORLD , &stat );
|
|
return status( stat );
|
|
}
|
|
|
|
void communicator::barrier()
|
|
{
|
|
MPI_Barrier( MPI_COMM_WORLD );
|
|
}
|
|
|
|
void broadcast( communicator & comm, int value, int root )
|
|
{
|
|
MPI_Bcast( &value, 1, MPI_INT, root, MPI_COMM_WORLD );
|
|
}
|
|
}
|