Commit df8bb4b4 authored by Praetorius, Simon's avatar Praetorius, Simon

small errors corrected

parent 99df86e6
......@@ -3,6 +3,7 @@ install(FILES
Common.hpp
Communicator.hpp
Environment.hpp
RecvDynamicSize.hpp
Request.hpp
RequestOperations.hpp
Serialization.hpp
......
......@@ -38,6 +38,16 @@ namespace mpi14
{
namespace definition
{
template <class F, class = Void_t<>>
struct Callable
: std::false_type {};
template <class F, class... Args>
struct Callable<F(Args...),
Void_t< decltype(std::declval<F>()(std::declval<Args>()...)) >>
: std::true_type {};
template <class F, class Sig, class = Void_t<>>
struct Functor
: std::false_type {};
......@@ -48,6 +58,9 @@ namespace mpi14
: std::is_convertible<std::result_of_t<F(Args...)>, R> {};
}
template <class F>
constexpr bool Callable = definition::Callable<F>::value;
template <class F, class Signature>
constexpr bool Functor = definition::Functor<F,Signature>::value;
}
......
......@@ -10,6 +10,7 @@
#include "Common.hpp"
#include "Request.hpp"
#include "RecvDynamicSize.hpp"
#include "Serialization.hpp"
#include "Type_Traits.hpp"
......@@ -69,7 +70,10 @@ namespace mpi14
REQUIRES( is_mpi_type<T> )>
void send(std::vector<T> const& vec, int to, int tag = 0) const;
void send(std::string const& str, int to, int tag = 0) const;
void send(std::string const& str, int to, int tag = 0) const
{
MPI_Send(str.data(), int(str.size()), MPI_CHAR, to, tag, comm_);
}
// send complex datatype:
// 1. create a binary representation of data, store it in a buffer
......@@ -106,7 +110,12 @@ namespace mpi14
REQUIRES( is_mpi_type<T> )>
Request isend(std::vector<T> const& vec, int to, int tag = 0) const;
Request isend(std::string const& str, int to, int tag = 0) const;
Request isend(std::string const& str, int to, int tag = 0) const
{
MPI_Request request;
MPI_Isend(str.data(), int(str.size()), MPI_CHAR, to, tag, comm_, &request);
return {request};
}
// send complex datatype: (non-blocking)
......@@ -147,7 +156,18 @@ namespace mpi14
REQUIRES( is_mpi_type<T> )>
MPI_Status recv(std::vector<T>& data, int from, int tag = 0) const;
MPI_Status recv(std::string& str, int from, int tag = 0) const;
MPI_Status recv(std::string& str, int from, int tag = 0) const
{
MPI_Status status;
MPI_Probe(from, tag, comm_, &status);
int size = 0;
MPI_Get_count(&status, MPI_CHAR, &size);
str.resize(size);
MPI_Recv(&str[0], size, MPI_CHAR, from, tag, comm_, MPI_STATUS_IGNORE);
return status;
}
// receive complex datatype
template <class Data,
......@@ -174,7 +194,15 @@ namespace mpi14
REQUIRES( is_mpi_type<T> )>
Request irecv(std::vector<T>& vec, int from, int tag = 0) const;
Request irecv(std::string& vec, int from, int tag = 0) const;
Request irecv(std::string& str, int from, int tag = 0) const
{
return {RecvDynamicSize(MPI_CHAR,from,tag,comm_,
[from,tag,comm=comm_,&str](int size)
{
str.resize(size);
MPI_Recv(&str[0], size, MPI_CHAR, from, tag, comm, MPI_STATUS_IGNORE);
}) };
}
// receive complex datatype asynchronousely
// Wait for data, by calling Future::test() or Future::wait().
......@@ -186,7 +214,21 @@ namespace mpi14
protected:
// free unused buffers
void check_buffers() const;
void check_buffers() const
{
using Buffers = std::decay_t<decltype(buffers_)>;
std::list<typename Buffers::iterator> remove;
for (auto it = buffers_.begin(); it != buffers_.end(); ++it) {
int flag;
MPI_Request_get_status(it->first, &flag, MPI_STATUS_IGNORE);
if (flag != 0)
remove.push_back(it);
}
for (auto it : remove)
buffers_.erase(it);
}
protected:
......@@ -197,7 +239,7 @@ namespace mpi14
int size_;
std::vector<char> buffer_;
mutable std::list< std::pair<MPI_Request*, std::string> > buffers_;
mutable std::list< std::pair<MPI_Request, std::string> > buffers_;
};
} // end namespace mpi14
......
......@@ -5,13 +5,16 @@
#include <boost/optional.hpp>
#include "Common.hpp"
namespace mpi14 {
class RecvDynamicSize
{
public:
template <class F>
template <class F,
REQUIRES( concepts::Callable<F(int)> )>
RecvDynamicSize(MPI_Datatype datatype, int from, int tag, MPI_Comm comm, F&& f)
: datatype_(datatype)
, from_(from)
......
install(FILES
Communicator.impl.hpp
RecvDynamicSize.impl.hpp
DESTINATION include/mpi14/impl/
)
#pragma once
#include "RecvDynamicSize.impl.hpp"
namespace mpi14 {
// send mpi datatype
......@@ -30,12 +28,6 @@ void Communicator::send(std::vector<T> const& vec, int to, int tag) const
}
void Communicator::send(std::string const& str, int to, int tag) const
{
MPI_Send(str.data(), int(str.size()), MPI_CHAR, to, tag, comm_);
}
// send complex datatype:
// 1. create a binary representation of data, store it in a buffer
// 2. send size of buffer (with MPI_Ibsend)
......@@ -105,14 +97,6 @@ Request Communicator::isend(std::vector<T> const& vec, int to, int tag) const
}
Request Communicator::isend(std::string const& str, int to, int tag) const
{
MPI_Request request;
MPI_Isend(str.data(), int(str.size()), MPI_CHAR, to, tag, comm_, &request);
return {request};
}
// send complex datatype: (non-blocking)
// 1. create a binary representation of data, store it in a buffer
// 2. send size of buffer (with MPI_Ibsend)
......@@ -122,9 +106,9 @@ template <class Data,
Request Communicator::isend(Data const& data, int to, int tag) const
{
check_buffers();
MPI_Request request;
buffers_.emplace_back(&request, serialization::store(data));
buffers_.emplace_back(MPI_Request{}, serialization::store(data));
auto& request = buffers_.back().first;
auto const& buffer = buffers_.back().second;
MPI_Isend(buffer.data(), int(buffer.size()), MPI_BYTE, to, tag, comm_, &request);
......@@ -172,20 +156,6 @@ MPI_Status Communicator::recv(std::vector<T>& vec, int from, int tag) const
}
MPI_Status Communicator::recv(std::string& str, int from, int tag) const
{
MPI_Status status;
MPI_Probe(from, tag, comm_, &status);
int size = 0;
MPI_Get_count(&status, MPI_CHAR, &size);
str.resize(size);
MPI_Recv(&str[0], size, MPI_CHAR, from, tag, comm_, MPI_STATUS_IGNORE);
return status;
}
// receive complex datatype
template <class Data,
REQUIRES( not is_mpi_type<Data> )>
......@@ -242,17 +212,6 @@ Request Communicator::irecv(std::vector<T>& vec, int from, int tag) const
}
Request Communicator::irecv(std::string& str, int from, int tag) const
{
return {RecvDynamicSize(MPI_CHAR,from,tag,comm_,
[from,tag,comm=comm_,&str](int size)
{
str.resize(size);
MPI_Recv(&str[0], size, MPI_CHAR, from, tag, comm, MPI_STATUS_IGNORE);
}) };
}
template <class Data,
REQUIRES( not is_mpi_type<Data> )>
Request Communicator::irecv(Data& data, int from, int tag) const
......@@ -268,22 +227,4 @@ Request Communicator::irecv(Data& data, int from, int tag) const
}) };
}
// -------------------------------------------------------------------------------------
void Communicator::check_buffers() const
{
using Buffers = std::decay_t<decltype(buffers_)>;
std::list<typename Buffers::iterator> remove;
for (auto it = buffers_.begin(); it != buffers_.end(); ++it) {
int flag;
MPI_Request_get_status(*it->first, &flag, MPI_STATUS_IGNORE);
if (flag != 0)
remove.push_back(it);
}
for (auto it : remove)
buffers_.erase(it);
}
} // end namespace mpi14
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment