Commit 957cf693 authored by Praetorius, Simon's avatar Praetorius, Simon

dynamic receiver calls functor with MPI_Status

parent 7765fcdd
......@@ -44,7 +44,7 @@ namespace mpi14
template <class F, class... Args>
struct Callable<F(Args...),
Void_t< decltype(std::declval<F>()(std::declval<Args>()...)) >>
Void_t< decltype(std::declval<std::decay_t<F>>()(std::declval<Args>()...)) >>
: std::true_type {};
......@@ -62,7 +62,7 @@ namespace mpi14
constexpr bool Callable = definition::Callable<F>::value;
template <class F, class Signature>
constexpr bool Functor = definition::Functor<F,Signature>::value;
constexpr bool Functor = definition::Functor<std::decay_t<F>,Signature>::value;
}
......
......@@ -186,6 +186,13 @@ namespace mpi14
std::enable_if_t<is_mpi_type<Data>::value, Request>
irecv(Data* data, std::size_t size, int from, int tag = 0) const;
template <class Receiver>
std::enable_if_t< concepts::Callable<Receiver(MPI_Status)>, Request>
irecv(Receiver&& recv, int from, int tag = 0) const
{
return { RecvDynamicSize(from, tag, comm_, std::forward<Receiver>(recv)) };
}
// receive vector of mpi datatypes
// 1. until message received, call MPI_Iprobe to retrieve status and size of message
// 2. resize data-vector
......@@ -196,11 +203,14 @@ namespace mpi14
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)
return {RecvDynamicSize(from,tag,comm_,
[comm=comm_,&str](MPI_Status 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);
MPI_Recv(&str[0], size, MPI_CHAR, status.MPI_SOURCE, status.MPI_TAG, comm, MPI_STATUS_IGNORE);
}) };
}
......
......@@ -14,10 +14,9 @@ namespace mpi14 {
public:
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)
REQUIRES( concepts::Callable<F(MPI_Status)> )>
RecvDynamicSize(int from, int tag, MPI_Comm comm, F&& f)
: from_(from)
, tag_(tag)
, comm_(comm)
, recv_(std::forward<F>(f))
......@@ -30,17 +29,12 @@ namespace mpi14 {
// Wait for a message from rank from_ with tag tag_
MPI_Iprobe(from_, tag_, comm_, &flag, &status_); // NOTE: maybe change to MPI_Improbe (for thread-savety)
if (flag != 0) {
// Find out the number of elements in the message
MPI_Get_count(&status_, datatype_, &size_);
if (flag != 0)
size_received_ = true;
}
}
if (size_received_ && !data_received_) {
recv_(size_);
recv_(status_);
data_received_ = true;
}
......@@ -53,11 +47,10 @@ namespace mpi14 {
private:
MPI_Datatype datatype_;
int from_;
int tag_;
MPI_Comm comm_;
std::function<void(int)> recv_;
std::function<void(MPI_Status)> recv_;
bool size_received_ = false;
bool data_received_ = false;
......
......@@ -203,11 +203,14 @@ template <class T>
std::enable_if_t<is_mpi_type<T>::value, Request>
Communicator::irecv(std::vector<T>& vec, int from, int tag) const
{
return {RecvDynamicSize(type_to_mpi<T>(),from,tag,comm_,
[from,tag,comm=comm_,&vec](int size)
return {RecvDynamicSize(from,tag,comm_,
[comm=comm_,&vec](MPI_Status status)
{
int size = 0;
MPI_Get_count(&status, type_to_mpi<T>(), &size);
vec.resize(size);
MPI_Recv(vec.data(), size, type_to_mpi<T>(), from, tag, comm, MPI_STATUS_IGNORE);
MPI_Recv(vec.data(), size, type_to_mpi<T>(), status.MPI_SOURCE, status.MPI_TAG, comm, MPI_STATUS_IGNORE);
}) };
}
......@@ -216,13 +219,16 @@ template <class Data>
std::enable_if_t<!is_mpi_type<Data>::value, Request>
Communicator::irecv(Data& data, int from, int tag) const
{
return {RecvDynamicSize(MPI_BYTE,from,tag,comm_,
[from,tag,comm=comm_,&data](int size)
return {RecvDynamicSize(from,tag,comm_,
[comm=comm_,&data](MPI_Status status)
{
int size = 0;
MPI_Get_count(&status, MPI_BYTE, &size);
std::vector<char> buffer(size);
// Receive the message. ignore the status
MPI_Recv(buffer.data(), size, MPI_BYTE, from, tag, comm, MPI_STATUS_IGNORE);
MPI_Recv(buffer.data(), size, MPI_BYTE, status.MPI_SOURCE, status.MPI_TAG, comm, MPI_STATUS_IGNORE);
serialization::load(buffer, data);
}) };
}
......
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