Loading...
Searching...
No Matches
p2pcommunicator.hh
/*
Copyright 2015 IRIS AS
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DUNE_COMMUNICATOR_HEADER_INCLUDED
#define DUNE_COMMUNICATOR_HEADER_INCLUDED
#include <cassert>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <dune/common/parallel/mpihelper.hh>
#include <dune/common/parallel/communication.hh>
// the following implementation is only available in case MPI is available
#if HAVE_MPI
#include <dune/common/parallel/mpicommunication.hh>
#endif
namespace Dune
{
class SimpleMessageBuffer
{
typedef std::vector< char > BufferType;
mutable BufferType buffer_;
const double factor_;
mutable size_t pos_;
public:
explicit SimpleMessageBuffer( const double factor = 1.1 )
: buffer_(), factor_( factor )
{
resetReadPosition();
}
void clear() { buffer_.clear(); resetReadPosition(); }
void resetReadPosition() { pos_ = 0 ; }
size_t size() const { return buffer_.size(); }
void reserve( const size_t size )
{
buffer_.reserve( size );
}
void resize( const size_t size )
{
buffer_.resize( size );
}
template <class T>
void write( const T& value )
{
// union to access bytes in value
const size_t tsize = sizeof( T );
size_t pos = buffer_.size();
const size_t sizeNeeded = pos + tsize ;
// reserve with some 10% overestimation
if( buffer_.capacity() < sizeNeeded )
{
reserve( size_t(factor_ * sizeNeeded) ) ;
}
// resize to size need to store value
buffer_.resize( sizeNeeded );
// copy value to buffer
std::copy_n( reinterpret_cast<const char *> (&value), tsize, buffer_.data()+pos );
}
void write( const std::string& str)
{
int size = str.size();
write(size);
for (int k = 0; k < size; ++k) {
write(str[k]);
}
}
template <class T>
void read( T& value ) const
{
// read bytes from stream and store in value
const size_t tsize = sizeof( T );
assert( pos_ + tsize <= buffer_.size() );
std::copy_n( buffer_.data()+pos_, tsize, reinterpret_cast<char *> (&value) );
pos_ += tsize;
}
void read( std::string& str) const
{
int size = 0;
read(size);
str.resize(size);
for (int k = 0; k < size; ++k) {
read(str[k]);
}
}
std::pair< char* , int > buffer() const
{
return std::make_pair( buffer_.data(), int(buffer_.size()) );
}
};
template < class MsgBuffer >
class Point2PointCommunicator : public Dune::Communication< MPIHelper::MPICommunicator >
{
public:
typedef MPIHelper::MPICommunicator MPICommunicator ;
typedef MsgBuffer MessageBufferType ;
protected:
using BaseType = Dune::Communication<MPICommunicator>;
typedef Point2PointCommunicator< MessageBufferType > ThisType;
// starting message tag
static const int messagetag = 234;
typedef std::map< int, int > linkage_t;
typedef std::vector< int > vector_t;
linkage_t sendLinkage_ ;
linkage_t recvLinkage_ ;
vector_t sendDest_ ;
vector_t recvSource_ ;
mutable vector_t _recvBufferSizes;
mutable bool _recvBufferSizesComputed;
public :
using BaseType :: rank;
using BaseType :: size;
/* \brief data handle interface that needs to be implemented for use with some of
* the exchange methods */
class DataHandleInterface
{
protected:
DataHandleInterface () {}
public:
virtual ~DataHandleInterface () {}
virtual void pack( const int link, MessageBufferType& os ) = 0 ;
virtual void unpack( const int link, MessageBufferType& os ) = 0 ;
// should contain work that could be done between send and receive
virtual void localComputation () {}
};
public:
explicit Point2PointCommunicator( const MPICommunicator& mpiComm = MPIHelper::getCommunicator() )
: BaseType( mpiComm ) { removeLinkage(); }
explicit Point2PointCommunicator( const BaseType& comm ) : BaseType( comm ) { removeLinkage(); }
inline void insertRequest( const std::set< int >& sendLinks, const std::set< int >& recvLinks );
inline int sendLinks () const { return sendLinkage_.size(); }
inline int recvLinks () const { return recvLinkage_.size(); }
const vector_t& recvBufferSizes() const { return _recvBufferSizes; }
inline int sendLink (const int rank) const
{
assert (sendLinkage_.end () != sendLinkage_.find (rank)) ;
return (* sendLinkage_.find (rank)).second ;
}
inline int recvLink (const int rank) const
{
assert (recvLinkage_.end () != recvLinkage_.find (rank)) ;
return (* recvLinkage_.find (rank)).second ;
}
const std::vector< int > &sendDest () const { return sendDest_; }
const std::vector< int > &recvSource () const { return recvSource_; }
inline void removeLinkage () ;
virtual std::vector< MessageBufferType > exchange (const std::vector< MessageBufferType > &) const;
virtual void exchange ( DataHandleInterface& ) const;
virtual void exchangeCached ( DataHandleInterface& ) const;
protected:
inline void computeDestinations( const linkage_t& linkage, vector_t& dest );
// return new tag number for the exchange messages
int getMessageTag(const unsigned int increment) const
{
const int retTag = this->tag_;
this->generateNextMessageTag(increment);
return retTag;
}
// return new tag number for the exchange messages
int getMessageTag() const
{
return this->getMessageTag(1u);
}
private:
mutable int tag_{messagetag + 2};
void generateNextMessageTag(const unsigned int increment) const
{
this->tag_ += increment;
// Reset to initial value if next tag exceeds MPI standard's maximum
// message tag guarantee of 2^15-1.
if (this->tag_ >= (1 << 15) - 1)
{
this->tag_ = messagetag + 2;
}
}
};
} // namespace Dune
// include inline implementation
#include "p2pcommunicator_impl.hh"
#endif // #ifndef DUNE_COMMUNICATOR_HEADER_INCLUDED
Dune::Point2PointCommunicator< MessageBufferType >
Dune::Point2PointCommunicator::MessageBufferType
MsgBuffer MessageBufferType
type of message buffer used
Definition p2pcommunicator.hh:138
Dune::Point2PointCommunicator< MessageBufferType >::recvLinks
int recvLinks() const
Definition p2pcommunicator.hh:193
Dune::Point2PointCommunicator::recvLink
int recvLink(const int rank) const
return recv link number for a given recv rank number
Definition p2pcommunicator.hh:206
Dune::Point2PointCommunicator::exchange
virtual void exchange(DataHandleInterface &) const
exchange data with peers, handle defines pack and unpack of data
Definition p2pcommunicator_impl.hh:586
Dune::Point2PointCommunicator::sendDest
const std::vector< int > & sendDest() const
return vector containing all process numbers we will send to
Definition p2pcommunicator.hh:213
Dune::Point2PointCommunicator::recvSource
const std::vector< int > & recvSource() const
return vector containing all process numbers we will receive from
Definition p2pcommunicator.hh:215
Dune::Point2PointCommunicator::MPICommunicator
MPIHelper::MPICommunicator MPICommunicator
type of MPI communicator, either MPI_Comm or NoComm as defined in MPIHelper
Definition p2pcommunicator.hh:135
Dune::Point2PointCommunicator::sendLink
int sendLink(const int rank) const
return send link number for a given send rank number
Definition p2pcommunicator.hh:199
Dune::Point2PointCommunicator::exchangeCached
virtual void exchangeCached(DataHandleInterface &) const
exchange data with peers, handle defines pack and unpack of data, if receive buffers are known from p...
Definition p2pcommunicator_impl.hh:620
Dune::Point2PointCommunicator< MessageBufferType >::sendLinks
int sendLinks() const
Definition p2pcommunicator.hh:190
Dune::Point2PointCommunicator::recvBufferSizes
const vector_t & recvBufferSizes() const
return vector containing possible recv buffer sizes
Definition p2pcommunicator.hh:196
Dune::Point2PointCommunicator::exchange
virtual std::vector< MessageBufferType > exchange(const std::vector< MessageBufferType > &) const
exchange message buffers with peers defined by inserted linkage
Definition p2pcommunicator_impl.hh:600
Dune::Point2PointCommunicator::Point2PointCommunicator
Point2PointCommunicator(const MPICommunicator &mpiComm=MPIHelper::getCommunicator())
constructor taking mpi communicator
Definition p2pcommunicator.hh:179
Dune::Point2PointCommunicator::insertRequest
void insertRequest(const std::set< int > &sendLinks, const std::set< int > &recvLinks)
insert communication request with a set os ranks to send to and a set of ranks to receive from
Definition p2pcommunicator_impl.hh:59
Dune::Point2PointCommunicator::removeLinkage
void removeLinkage()
remove stored linkage
Definition p2pcommunicator_impl.hh:30
Dune::Point2PointCommunicator::Point2PointCommunicator
Point2PointCommunicator(const BaseType &comm)
constructor taking collective communication
Definition p2pcommunicator.hh:183
Dune::SimpleMessageBuffer::resetReadPosition
void resetReadPosition()
reset read position of buffer to beginning
Definition p2pcommunicator.hh:57
Dune::SimpleMessageBuffer::size
size_t size() const
return size of buffer
Definition p2pcommunicator.hh:59
Dune::SimpleMessageBuffer::buffer
std::pair< char *, int > buffer() const
return pointer to buffer and size for use with MPI functions
Definition p2pcommunicator.hh:123
Dune::SimpleMessageBuffer::clear
void clear()
clear the buffer
Definition p2pcommunicator.hh:55
Dune::SimpleMessageBuffer::reserve
void reserve(const size_t size)
reserve memory for 'size' entries
Definition p2pcommunicator.hh:62
Dune::SimpleMessageBuffer::resize
void resize(const size_t size)
resize buffer to 'size' entries
Definition p2pcommunicator.hh:68
Dune::SimpleMessageBuffer::SimpleMessageBuffer
SimpleMessageBuffer(const double factor=1.1)
constructor taking memory reserve estimation factor (default is 1.1, i.e.
Definition p2pcommunicator.hh:48
Dune::SimpleMessageBuffer::read
void read(T &value) const
read value from buffer, value must implement the operator= correctly (i.e.
Definition p2pcommunicator.hh:103
Dune::SimpleMessageBuffer::write
void write(const T &value)
write value to buffer, value must implement the operator= correctly (i.e.
Definition p2pcommunicator.hh:75
Dune
The namespace Dune is the main namespace for all Dune code.
Definition CartesianIndexMapper.hpp:10