/* (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 */ # 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 ); } }