-/* Copyright (c) 2007-2021. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+#include <simgrid/modelchecker.h>
#include "smpi_win.hpp"
#include "private.hpp"
#include "smpi_keyvals.hpp"
#include "smpi_request.hpp"
#include "src/smpi/include/smpi_actor.hpp"
+#include "src/mc/mc_replay.hpp"
#include <algorithm>
if(info!=MPI_INFO_NULL)
info->ref();
connected_wins_[rank_] = this;
- if(rank_==0){
- bar_ = new s4u::Barrier(comm->size());
- }
errhandler_->ref();
comm->add_rma_win(this);
comm->ref();
colls::allgather(&connected_wins_[rank_], sizeof(MPI_Win), MPI_BYTE, connected_wins_.data(), sizeof(MPI_Win),
MPI_BYTE, comm);
-
- colls::bcast(&bar_, sizeof(s4u::Barrier*), MPI_BYTE, 0, comm);
-
- colls::barrier(comm);
+ if (MC_is_active() || MC_record_replay_is_active()){
+ s4u::Barrier* bar_ptr;
+ if (rank_ == 0) {
+ bar_ = s4u::Barrier::create(comm->size());
+ bar_ptr = bar_.get();
+ }
+ colls::bcast(&bar_ptr, sizeof(s4u::Barrier*), MPI_BYTE, 0, comm);
+ if (rank_ != 0)
+ bar_ = s4u::BarrierPtr(bar_ptr);
+ }
this->add_f();
}
-Win::~Win(){
+int Win::del(Win* win){
//As per the standard, perform a barrier to ensure every async comm is finished
- bar_->wait();
-
- flush_local_all();
-
- if (info_ != MPI_INFO_NULL)
- simgrid::smpi::Info::unref(info_);
- if (errhandler_ != MPI_ERRHANDLER_NULL)
- simgrid::smpi::Errhandler::unref(errhandler_);
-
- comm_->remove_rma_win(this);
-
- colls::barrier(comm_);
- Comm::unref(comm_);
-
- if (rank_ == 0)
- delete bar_;
+ if (MC_is_active() || MC_record_replay_is_active())
+ win->bar_->wait();
+ else
+ colls::barrier(win->comm_);
+ win->flush_local_all();
+
+ if (win->info_ != MPI_INFO_NULL)
+ simgrid::smpi::Info::unref(win->info_);
+ if (win->errhandler_ != MPI_ERRHANDLER_NULL)
+ simgrid::smpi::Errhandler::unref(win->errhandler_);
+
+ win->comm_->remove_rma_win(win);
+
+ colls::barrier(win->comm_);
+ Comm::unref(win->comm_);
+ if (!win->lockers_.empty() || win->opened_ < 0){
+ XBT_WARN("Freeing a locked or opened window");
+ return MPI_ERR_WIN;
+ }
+ if (win->allocated_)
+ xbt_free(win->base_);
- if (allocated_)
- xbt_free(base_);
+ F2C::free_f(win->f2c_id());
+ win->cleanup_attr<Win>();
- F2C::free_f(this->f2c_id());
- cleanup_attr<Win>();
+ delete win;
+ return MPI_SUCCESS;
}
int Win::attach(void* /*base*/, MPI_Aint size)
MPI_Info Win::info()
{
- if (info_ == MPI_INFO_NULL)
- info_ = new Info();
- info_->ref();
return info_;
}
int Win::fence(int assert)
{
XBT_DEBUG("Entering fence");
- if (opened_ == 0)
- opened_=1;
+ opened_++;
if (not (assert & MPI_MODE_NOPRECEDE)) {
// This is not the first fence => finalize what came before
- bar_->wait();
+ if (MC_is_active() || MC_record_replay_is_active())
+ bar_->wait();
+ else
+ colls::barrier(comm_);
flush_local_all();
count_=0;
}
if (assert & MPI_MODE_NOSUCCEED) // there should be no ops after this one, tell we are closed.
opened_=0;
assert_ = assert;
-
- bar_->wait();
+ if (MC_is_active() || MC_record_replay_is_active())
+ bar_->wait();
+ else
+ colls::barrier(comm_);
XBT_DEBUG("Leaving fence");
return MPI_SUCCESS;
mut_->unlock();
}
+ // FIXME: The current implementation fails to ensure the correct ordering of the accumulate requests. The following
+ // 'flush' is a workaround to fix that.
+ flush(target_rank);
XBT_DEBUG("Leaving MPI_Win_Accumulate");
return MPI_SUCCESS;
}
group->ref();
dst_group_ = group;
- opened_++; // we're open for business !
+ opened_--; // we're open for business !
XBT_DEBUG("Leaving MPI_Win_Start");
return MPI_SUCCESS;
}
group->ref();
src_group_ = group;
- opened_++; // we're open for business !
+ opened_--; // we're open for business !
XBT_DEBUG("Leaving MPI_Win_Post");
return MPI_SUCCESS;
}
flush_local_all();
- opened_--; //we're closed for business !
+ opened_++; //we're closed for business !
Group::unref(dst_group_);
dst_group_ = MPI_GROUP_NULL;
return MPI_SUCCESS;
flush_local_all();
- opened_--; //we're closed for business !
+ opened_++; //we're closed for business !
Group::unref(src_group_);
src_group_ = MPI_GROUP_NULL;
return MPI_SUCCESS;