#include "private.hpp"
#include "simgrid/Exception.hpp"
#include "simgrid/s4u/Exec.hpp"
+#include "simgrid/s4u/Mutex.hpp"
+#include "simgrid/s4u/ConditionVariable.hpp"
#include "smpi_comm.hpp"
#include "smpi_datatype.hpp"
#include "smpi_host.hpp"
namespace simgrid{
namespace smpi{
-Request::Request(const void* buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm,
+Request::Request(const void* buf, int count, MPI_Datatype datatype, aid_t src, aid_t dst, int tag, MPI_Comm comm,
unsigned flags, MPI_Op op)
: buf_(const_cast<void*>(buf))
, old_type_(datatype)
refcount_ = 1;
else
refcount_ = 0;
- cancelled_ = 0;
nbc_requests_=nullptr;
nbc_requests_size_=0;
init_buffer(count);
+ this->add_f();
}
void Request::ref(){
void Request::unref(MPI_Request* request)
{
- if((*request) != MPI_REQUEST_NULL){
- (*request)->refcount_--;
- if((*request)->refcount_ < 0) {
- (*request)->print_request("wrong refcount");
- xbt_die("Whoops, wrong refcount");
- }
- if((*request)->refcount_==0){
- if ((*request)->flags_ & MPI_REQ_GENERALIZED){
- ((*request)->generalized_funcs)->free_fn(((*request)->generalized_funcs)->extra_state);
- }else{
- Comm::unref((*request)->comm_);
- Datatype::unref((*request)->old_type_);
- }
- if ((*request)->op_!=MPI_REPLACE && (*request)->op_!=MPI_OP_NULL)
- Op::unref(&(*request)->op_);
+ xbt_assert(*request != MPI_REQUEST_NULL, "freeing an already free request");
- (*request)->print_request("Destroying");
- delete *request;
- *request = MPI_REQUEST_NULL;
- }else{
- (*request)->print_request("Decrementing");
+ (*request)->refcount_--;
+ if ((*request)->refcount_ < 0) {
+ (*request)->print_request("wrong refcount");
+ xbt_die("Whoops, wrong refcount");
+ }
+ if ((*request)->refcount_ == 0) {
+ if ((*request)->flags_ & MPI_REQ_GENERALIZED) {
+ ((*request)->generalized_funcs)->free_fn(((*request)->generalized_funcs)->extra_state);
+ } else {
+ Comm::unref((*request)->comm_);
+ Datatype::unref((*request)->old_type_);
}
- }else{
- xbt_die("freeing an already free request");
+ if ((*request)->op_ != MPI_REPLACE && (*request)->op_ != MPI_OP_NULL)
+ Op::unref(&(*request)->op_);
+
+ (*request)->print_request("Destroying");
+ F2C::free_f((*request)->f2c_id());
+ delete *request;
+ *request = MPI_REQUEST_NULL;
+ } else {
+ (*request)->print_request("Decrementing");
}
}
{
xbt_assert(sender, "Cannot match against null sender");
xbt_assert(receiver, "Cannot match against null receiver");
- XBT_DEBUG("Trying to match %s of sender src %d against %d, tag %d against %d, id %d against %d",
+ XBT_DEBUG("Trying to match %s of sender src %ld against %ld, tag %d against %d, id %d against %d",
(req == receiver ? "send" : "recv"), sender->src_, receiver->src_, sender->tag_, receiver->tag_,
sender->comm_->id(), receiver->comm_->id());
receiver->real_src_ = sender->src_;
if (receiver->tag_ == MPI_ANY_TAG)
receiver->real_tag_ = sender->tag_;
- if (receiver->real_size_ < sender->real_size_){
- XBT_DEBUG("Truncating message - should not happen: receiver size : %zu < sender size : %zu", receiver->real_size_, sender->real_size_);
- receiver->truncated_ = true;
+ if ((receiver->flags_ & MPI_REQ_PROBE) == 0 ){
+ if (receiver->real_size_ < sender->real_size_){
+ XBT_DEBUG("Truncating message - should not happen: receiver size : %zu < sender size : %zu", receiver->real_size_, sender->real_size_);
+ receiver->truncated_ = true;
+ } else if (receiver->real_size_ > sender->real_size_){
+ receiver->real_size_=sender->real_size_;
+ }
}
if (sender->detached_)
receiver->detached_sender_ = sender; // tie the sender to the receiver, as it is detached and has to be freed in
// the receiver
- if (req->cancelled_ == 0)
- req->cancelled_ = -1; // mark as uncancelable
+ req->flags_ |= MPI_REQ_MATCHED; // mark as impossible to cancel anymore
XBT_DEBUG("match succeeded");
return true;
}
void Request::print_request(const char* message) const
{
- XBT_VERB("%s request %p [buf = %p, size = %zu, src = %d, dst = %d, tag = %d, flags = %x]",
- message, this, buf_, size_, src_, dst_, tag_, flags_);
+ XBT_VERB("%s request %p [buf = %p, size = %zu, src = %ld, dst = %ld, tag = %d, flags = %x]", message, this, buf_,
+ size_, src_, dst_, tag_, flags_);
}
/* factories, to hide the internal flags from the caller */
MPI_Request Request::bsend_init(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
{
return new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_PERSISTENT | MPI_REQ_SEND | MPI_REQ_PREPARED | MPI_REQ_BSEND);
}
MPI_Request Request::send_init(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
{
return new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_PERSISTENT | MPI_REQ_SEND | MPI_REQ_PREPARED);
}
MPI_Request Request::ssend_init(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
{
return new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_PERSISTENT | MPI_REQ_SSEND | MPI_REQ_SEND | MPI_REQ_PREPARED);
}
MPI_Request Request::isend_init(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
{
return new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_PREPARED);
}
-
MPI_Request Request::rma_send_init(const void *buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm,
MPI_Op op)
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
if(op==MPI_OP_NULL){
- request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src)->get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src),
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_PREPARED);
}else{
- request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src)->get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src),
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_PREPARED |
- MPI_REQ_ACCUMULATE, op);
+ MPI_REQ_ACCUMULATE,
+ op);
}
return request;
}
MPI_Request Request::recv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm)
{
+ aid_t source = MPI_PROC_NULL;
+ if (src == MPI_ANY_SOURCE)
+ source = MPI_ANY_SOURCE;
+ else if (src != MPI_PROC_NULL)
+ source = comm->group()->actor(src);
return new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype,
- src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : comm->group()->actor(src)->get_pid(),
+ source,
simgrid::s4u::this_actor::get_pid(), tag, comm,
MPI_REQ_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED);
}
MPI_Op op)
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
+ aid_t source = MPI_PROC_NULL;
+ if (src == MPI_ANY_SOURCE)
+ source = MPI_ANY_SOURCE;
+ else if (src != MPI_PROC_NULL)
+ source = comm->group()->actor(src);
if(op==MPI_OP_NULL){
- request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src)->get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, source,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED);
}else{
- request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src)->get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
- MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED | MPI_REQ_ACCUMULATE, op);
+ request =
+ new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, source,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
+ MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED | MPI_REQ_ACCUMULATE, op);
}
return request;
}
MPI_Request Request::irecv_init(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm)
{
+ aid_t source = MPI_PROC_NULL;
+ if (src == MPI_ANY_SOURCE)
+ source = MPI_ANY_SOURCE;
+ else if (src != MPI_PROC_NULL)
+ source = comm->group()->actor(src);
return new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype,
- src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : comm->group()->actor(src)->get_pid(),
- simgrid::s4u::this_actor::get_pid(), tag, comm,
+ source, simgrid::s4u::this_actor::get_pid(), tag, comm,
MPI_REQ_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED);
}
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_BSEND);
- request->start();
+ if(dst != MPI_PROC_NULL)
+ request->start();
return request;
}
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND);
- request->start();
+ if(dst != MPI_PROC_NULL)
+ request->start();
return request;
}
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SSEND | MPI_REQ_SEND);
- request->start();
+ if(dst != MPI_PROC_NULL)
+ request->start();
return request;
}
-
MPI_Request Request::irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm)
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
+ aid_t source = MPI_PROC_NULL;
+ if (src == MPI_ANY_SOURCE)
+ source = MPI_ANY_SOURCE;
+ else if (src != MPI_PROC_NULL)
+ source = comm->group()->actor(src);
request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype,
- src == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : comm->group()->actor(src)->get_pid(),
- simgrid::s4u::this_actor::get_pid(), tag, comm, MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV);
- request->start();
+ source, simgrid::s4u::this_actor::get_pid(), tag, comm,
+ MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV);
+ if(src != MPI_PROC_NULL)
+ request->start();
return request;
}
-void Request::recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
+int Request::recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status * status)
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
request = irecv(buf, count, datatype, src, tag, comm);
- wait(&request,status);
+ int retval = wait(&request,status);
request = nullptr;
+ return retval;
}
void Request::bsend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm, MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND | MPI_REQ_BSEND);
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
+ MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND | MPI_REQ_BSEND);
- request->start();
+ if(dst != MPI_PROC_NULL)
+ request->start();
wait(&request, MPI_STATUS_IGNORE);
request = nullptr;
}
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm, MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND);
-
- request->start();
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
+ MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND);
+ if(dst != MPI_PROC_NULL)
+ request->start();
wait(&request, MPI_STATUS_IGNORE);
request = nullptr;
}
{
MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
- comm->group()->actor(dst)->get_pid(), tag, comm,
+ dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL, tag, comm,
MPI_REQ_NON_PERSISTENT | MPI_REQ_SSEND | MPI_REQ_SEND);
- request->start();
+ if(dst != MPI_PROC_NULL)
+ request->start();
wait(&request,MPI_STATUS_IGNORE);
request = nullptr;
}
void *recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag,
MPI_Comm comm, MPI_Status * status)
{
+ aid_t source = MPI_PROC_NULL;
+ if (src == MPI_ANY_SOURCE)
+ source = MPI_ANY_SOURCE;
+ else if (src != MPI_PROC_NULL)
+ source = comm->group()->actor(src);
+ aid_t destination = dst != MPI_PROC_NULL ? comm->group()->actor(dst) : MPI_PROC_NULL;
+
std::array<MPI_Request, 2> requests;
std::array<MPI_Status, 2> stats;
- int myid = simgrid::s4u::this_actor::get_pid();
- if ((comm->group()->actor(dst)->get_pid() == myid) && (comm->group()->actor(src)->get_pid() == myid)) {
+ aid_t myid = simgrid::s4u::this_actor::get_pid();
+ if ((destination == myid) && (source == myid)) {
Datatype::copy(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype);
if (status != MPI_STATUS_IGNORE) {
- status->MPI_SOURCE = src;
+ status->MPI_SOURCE = source;
status->MPI_TAG = recvtag;
status->MPI_ERROR = MPI_SUCCESS;
status->count = sendcount * sendtype->size();
mut->unlock();
} else { /* the RECV flag was not set, so this is a send */
const simgrid::smpi::ActorExt* process = smpi_process_remote(simgrid::s4u::Actor::by_pid(dst_));
- xbt_assert(process, "Actor pid=%d is gone??", dst_);
- int rank = src_;
- if (TRACE_smpi_view_internals()) {
- TRACE_smpi_send(rank, rank, dst_, tag_, size_);
- }
+ xbt_assert(process, "Actor pid=%ld is gone??", dst_);
+ if (TRACE_smpi_view_internals())
+ TRACE_smpi_send(src_, src_, dst_, tag_, size_);
this->print_request("New send");
void* buf = buf_;
}
size_t payload_size_ = size_ + 16;//MPI enveloppe size (tag+dest+communicator)
- action_ = simcall_comm_isend(
- simgrid::s4u::Actor::by_pid(src_)->get_impl(), mailbox->get_impl(), payload_size_, -1.0, buf, real_size_, &match_send,
+ action_ = simcall_comm_isend(
+ simgrid::kernel::actor::ActorImpl::by_pid(src_), mailbox->get_impl(), payload_size_, -1.0, buf, real_size_,
+ &match_send,
&xbt_free_f, // how to free the userdata if a detached send fails
process->replaying() ? &smpi_comm_null_copy_buffer_callback : smpi_comm_copy_data_callback, this,
// detach if msg size < eager/rdv switch limit
return;
for(int i = 0; i < count; i++) {
- requests[i]->start();
+ if(requests[i]->src_ != MPI_PROC_NULL && requests[i]->dst_ != MPI_PROC_NULL)
+ requests[i]->start();
}
}
void Request::cancel()
{
- if(cancelled_!=-1)
- cancelled_=1;
+ this->flags_ |= MPI_REQ_CANCELLED;
if (this->action_ != nullptr)
(boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(this->action_))->cancel();
}
static int nsleeps = 1;
int ret = MPI_SUCCESS;
-
- // Are we testing a request meant for non blocking collectives ?
- // If so, test all the subrequests.
- if ((*request)->nbc_requests_size_>0){
- ret = testall((*request)->nbc_requests_size_, (*request)->nbc_requests_, flag, MPI_STATUSES_IGNORE);
- if(*flag){
- delete[] (*request)->nbc_requests_;
- (*request)->nbc_requests_size_=0;
- unref(request);
- }
- return ret;
- }
-
+
if(smpi_test_sleep > 0)
simgrid::s4u::this_actor::sleep_for(nsleeps * smpi_test_sleep);
Status::empty(status);
*flag = 1;
if (((*request)->flags_ & (MPI_REQ_PREPARED | MPI_REQ_FINISHED)) == 0) {
- if ((*request)->action_ != nullptr && (*request)->cancelled_ != 1){
+ if ((*request)->action_ != nullptr && ((*request)->flags_ & MPI_REQ_CANCELLED) == 0){
try{
*flag = simcall_comm_test((*request)->action_.get());
} catch (const Exception&) {
static int nsleeps = 1;
double speed = s4u::this_actor::get_host()->get_speed();
double maxrate = smpi_cfg_iprobe_cpu_usage();
- auto request = new Request(nullptr, 0, MPI_CHAR,
- source == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : comm->group()->actor(source)->get_pid(),
- simgrid::s4u::this_actor::get_pid(), tag, comm, MPI_REQ_PERSISTENT | MPI_REQ_RECV);
+ auto request =
+ new Request(nullptr, 0, MPI_CHAR, source == MPI_ANY_SOURCE ? MPI_ANY_SOURCE : comm->group()->actor(source),
+ simgrid::s4u::this_actor::get_pid(), tag, comm, MPI_REQ_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PROBE);
if (smpi_iprobe_sleep > 0) {
/** Compute the number of flops we will sleep **/
s4u::this_actor::exec_init(/*nsleeps: See comment above */ nsleeps *
xbt_assert(request == MPI_REQUEST_NULL);
}
+int Request::finish_nbc_requests(MPI_Request* request){
+ int ret = waitall((*request)->nbc_requests_size_, (*request)->nbc_requests_, MPI_STATUSES_IGNORE);
+ XBT_DEBUG("finish non blocking collective request with %d sub-requests", (*request)->nbc_requests_size_);
+ for (int i = 0; i < (*request)->nbc_requests_size_; i++) {
+ if((*request)->buf_!=nullptr && (*request)->nbc_requests_[i]!=MPI_REQUEST_NULL){//reduce case
+ void * buf=(*request)->nbc_requests_[i]->buf_;
+ if((*request)->old_type_->flags() & DT_FLAG_DERIVED)
+ buf=(*request)->nbc_requests_[i]->old_buf_;
+ if((*request)->nbc_requests_[i]->flags_ & MPI_REQ_RECV ){
+ if((*request)->op_!=MPI_OP_NULL){
+ int count=(*request)->size_/ (*request)->old_type_->size();
+ (*request)->op_->apply(buf, (*request)->buf_, &count, (*request)->old_type_);
+ }
+ smpi_free_tmp_buffer(static_cast<unsigned char*>(buf));
+ }
+ }
+ if((*request)->nbc_requests_[i]!=MPI_REQUEST_NULL)
+ Request::unref(&((*request)->nbc_requests_[i]));
+ }
+ delete[] (*request)->nbc_requests_;
+ (*request)->nbc_requests_size_=0;
+ return ret;
+}
+
void Request::finish_wait(MPI_Request* request, MPI_Status * status)
{
MPI_Request req = *request;
Status::empty(status);
-
- if (req->cancelled_==1){
+ if((req->flags_ & MPI_REQ_CANCELLED) != 0 && (req->flags_ & MPI_REQ_MATCHED) == 0) {
if (status!=MPI_STATUS_IGNORE)
status->cancelled=1;
if(req->detached_sender_ != nullptr)
return;
}
+ if ((*request)->flags() & MPI_REQ_NBC){
+ int ret = finish_nbc_requests(request);
+ if (ret != MPI_SUCCESS)
+ xbt_die("error when finishing non blocking collective requests");
+ }
+
if ((req->flags_ & (MPI_REQ_PREPARED | MPI_REQ_GENERALIZED | MPI_REQ_FINISHED)) == 0) {
- if(status != MPI_STATUS_IGNORE) {
- int src = req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_;
- status->MPI_SOURCE = req->comm_->group()->rank(src);
- status->MPI_TAG = req->tag_ == MPI_ANY_TAG ? req->real_tag_ : req->tag_;
- status->MPI_ERROR = req->truncated_ ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
+ if (status != MPI_STATUS_IGNORE) {
+ if (req->src_== MPI_PROC_NULL || req->dst_== MPI_PROC_NULL){
+ Status::empty(status);
+ status->MPI_SOURCE = MPI_PROC_NULL;
+ } else {
+ aid_t src = req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_;
+ status->MPI_SOURCE = req->comm_->group()->rank(src);
+ status->MPI_TAG = req->tag_ == MPI_ANY_TAG ? req->real_tag_ : req->tag_;
+ status->MPI_ERROR = req->truncated_ ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
+ }
// this handles the case were size in receive differs from size in send
status->count = req->real_size_;
}
}
if (TRACE_smpi_view_internals() && ((req->flags_ & MPI_REQ_RECV) != 0)) {
- int rank = simgrid::s4u::this_actor::get_pid();
- int src_traced = (req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_);
+ aid_t rank = simgrid::s4u::this_actor::get_pid();
+ aid_t src_traced = (req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_);
TRACE_smpi_recv(src_traced, rank,req->tag_);
}
if(req->detached_sender_ != nullptr){
simgrid::smpi::Errhandler::unref(err);
MC_assert(not MC_is_active()); /* Only fail in MC mode */
}
- unref(request);
-
+ if(req->src_ != MPI_PROC_NULL && req->dst_ != MPI_PROC_NULL)
+ unref(request);
}
int Request::wait(MPI_Request * request, MPI_Status * status)
xbt_assert(*request != MPI_REQUEST_NULL);
int ret=MPI_SUCCESS;
- // Are we waiting on a request meant for non blocking collectives ?
- // If so, wait for all the subrequests.
- if ((*request)->nbc_requests_size_>0){
- ret = waitall((*request)->nbc_requests_size_, (*request)->nbc_requests_, MPI_STATUSES_IGNORE);
- for (int i = 0; i < (*request)->nbc_requests_size_; i++) {
- if((*request)->buf_!=nullptr && (*request)->nbc_requests_[i]!=MPI_REQUEST_NULL){//reduce case
- void * buf=(*request)->nbc_requests_[i]->buf_;
- if((*request)->old_type_->flags() & DT_FLAG_DERIVED)
- buf=(*request)->nbc_requests_[i]->old_buf_;
- if((*request)->nbc_requests_[i]->flags_ & MPI_REQ_RECV ){
- if((*request)->op_!=MPI_OP_NULL){
- int count=(*request)->size_/ (*request)->old_type_->size();
- (*request)->op_->apply(buf, (*request)->buf_, &count, (*request)->old_type_);
- }
- smpi_free_tmp_buffer(static_cast<unsigned char*>(buf));
- }
- }
- if((*request)->nbc_requests_[i]!=MPI_REQUEST_NULL)
- Request::unref(&((*request)->nbc_requests_[i]));
+
+ if((*request)->src_ == MPI_PROC_NULL || (*request)->dst_ == MPI_PROC_NULL){
+ if (status != MPI_STATUS_IGNORE) {
+ Status::empty(status);
+ status->MPI_SOURCE = MPI_PROC_NULL;
}
- delete[] (*request)->nbc_requests_;
- (*request)->nbc_requests_size_=0;
- unref(request);
(*request)=MPI_REQUEST_NULL;
return ret;
}
ret = ((*request)->generalized_funcs)->query_fn(((*request)->generalized_funcs)->extra_state, mystatus);
}
+ if ((*request)->truncated_)
+ ret = MPI_ERR_TRUNCATE;
+
finish_wait(request, status); // may invalidate *request
if (*request != MPI_REQUEST_NULL && (((*request)->flags_ & MPI_REQ_NON_PERSISTENT) != 0))
*request = MPI_REQUEST_NULL;
*flag=0;
if(req != MPI_REQUEST_NULL && req->action_ != nullptr) {
- req->iprobe(req->src_, req->tag_, req->comm_, flag, status);
+ req->iprobe(req->comm_->group()->rank(req->src_), req->tag_, req->comm_, flag, status);
if(*flag)
return MPI_SUCCESS;
}
*flag=1;
if(req != MPI_REQUEST_NULL &&
status != MPI_STATUS_IGNORE) {
- int src = req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_;
+ aid_t src = req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_;
status->MPI_SOURCE = req->comm_->group()->rank(src);
status->MPI_TAG = req->tag_ == MPI_ANY_TAG ? req->real_tag_ : req->tag_;
status->MPI_ERROR = req->truncated_ ? MPI_ERR_TRUNCATE : MPI_SUCCESS;