From d5e0ea359062eb2dd4fa2d73a9d9c5f9bf89cb9e Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Fri, 24 Feb 2006 13:04:15 +0000 Subject: [PATCH] * Post and Start should only check their epoch types for conflicts, otherwise you can't be in a post and a start at the same time, and that is clearly legal to do * Fix interptretation of when the epochs start for MPI_Fence. Only start an epoch if communication actually occurs, otherwise it isn't actually an epoch. I don't know who thought that wording in the MPI standard was a good idea, but can't change it now... This commit was SVN r9139. --- ompi/mca/osc/pt2pt/osc_pt2pt.c | 7 ------- ompi/mca/osc/pt2pt/osc_pt2pt_comm.c | 21 ++++++++++++++++++++- ompi/mca/osc/pt2pt/osc_pt2pt_sync.c | 18 +++++++++--------- ompi/mpi/c/accumulate.c | 2 +- ompi/mpi/c/get.c | 2 +- ompi/mpi/c/put.c | 2 +- ompi/mpi/c/win_free.c | 14 ++++---------- ompi/mpi/c/win_lock.c | 4 +--- ompi/mpi/c/win_post.c | 5 +---- ompi/mpi/c/win_start.c | 5 +---- ompi/win/win.h | 21 ++++++++++++++++++--- 11 files changed, 57 insertions(+), 44 deletions(-) diff --git a/ompi/mca/osc/pt2pt/osc_pt2pt.c b/ompi/mca/osc/pt2pt/osc_pt2pt.c index 3004e79b93..c8a97e11af 100644 --- a/ompi/mca/osc/pt2pt/osc_pt2pt.c +++ b/ompi/mca/osc/pt2pt/osc_pt2pt.c @@ -33,13 +33,6 @@ ompi_osc_pt2pt_module_free(ompi_win_t *win) int tmp; ompi_osc_pt2pt_module_t *module = P2P_MODULE(win); - if ((OMPI_WIN_ACCESS_EPOCH & win->w_flags) || - (OMPI_WIN_EXPOSE_EPOCH & win->w_flags)) { - /* finish off the epoch. More for sanity checks than anything - - could really just ignore this condition... */ - ret = ompi_osc_pt2pt_module_fence(MPI_MODE_NOPRECEDE|MPI_MODE_NOSUCCEED, win); - } - /* finish with a barrier */ if (ompi_group_size(win->w_group) > 1) { ret = module->p2p_comm->c_coll.coll_barrier(module->p2p_comm); diff --git a/ompi/mca/osc/pt2pt/osc_pt2pt_comm.c b/ompi/mca/osc/pt2pt/osc_pt2pt_comm.c index 18a1f50788..66ca9bb9d5 100644 --- a/ompi/mca/osc/pt2pt/osc_pt2pt_comm.c +++ b/ompi/mca/osc/pt2pt/osc_pt2pt_comm.c @@ -47,7 +47,14 @@ ompi_osc_pt2pt_module_accumulate(void *origin_addr, int origin_count, int ret; ompi_osc_pt2pt_sendreq_t *sendreq; - if (!ompi_ddt_is_predefined(target_dt)) { + if (OMPI_WIN_FENCE & ompi_win_get_mode(win)) { + /* well, we're definitely in an access epoch now */ + ompi_win_set_mode(win, OMPI_WIN_FENCE | OMPI_WIN_ACCESS_EPOCH | + OMPI_WIN_EXPOSE_EPOCH); + } + + if (op != &ompi_mpi_op_replace && + !ompi_ddt_is_predefined(target_dt)) { fprintf(stderr, "MPI_Accumulate currently does not support reductions\n"); fprintf(stderr, "with any user-defined types. This will be rectified\n"); fprintf(stderr, "in a future release.\n"); @@ -89,6 +96,12 @@ ompi_osc_pt2pt_module_get(void *origin_addr, int ret; ompi_osc_pt2pt_sendreq_t *sendreq; + if (OMPI_WIN_FENCE & ompi_win_get_mode(win)) { + /* well, we're definitely in an access epoch now */ + ompi_win_set_mode(win, OMPI_WIN_FENCE | OMPI_WIN_ACCESS_EPOCH | + OMPI_WIN_EXPOSE_EPOCH); + } + /* create sendreq */ ret = ompi_osc_pt2pt_sendreq_alloc_init(OMPI_OSC_PT2PT_GET, origin_addr, @@ -118,6 +131,12 @@ ompi_osc_pt2pt_module_put(void *origin_addr, int origin_count, int ret; ompi_osc_pt2pt_sendreq_t *sendreq; + if (OMPI_WIN_FENCE & ompi_win_get_mode(win)) { + /* well, we're definitely in an access epoch now */ + ompi_win_set_mode(win, OMPI_WIN_FENCE | OMPI_WIN_ACCESS_EPOCH | + OMPI_WIN_EXPOSE_EPOCH); + } + /* create sendreq */ ret = ompi_osc_pt2pt_sendreq_alloc_init(OMPI_OSC_PT2PT_PUT, origin_addr, diff --git a/ompi/mca/osc/pt2pt/osc_pt2pt_sync.c b/ompi/mca/osc/pt2pt/osc_pt2pt_sync.c index aa0b9673bd..074cce49ac 100644 --- a/ompi/mca/osc/pt2pt/osc_pt2pt_sync.c +++ b/ompi/mca/osc/pt2pt/osc_pt2pt_sync.c @@ -175,7 +175,7 @@ ompi_osc_pt2pt_module_fence(int assert, ompi_win_t *win) /* all transfers are done - back to the real world we go */ if (0 == (assert & MPI_MODE_NOSUCCEED)) { - ompi_win_set_mode(win, OMPI_WIN_ACCESS_EPOCH | OMPI_WIN_EXPOSE_EPOCH); + ompi_win_set_mode(win, OMPI_WIN_FENCE); } else { ompi_win_set_mode(win, 0); } @@ -189,15 +189,15 @@ ompi_osc_pt2pt_module_start(ompi_group_t *group, int assert, ompi_win_t *win) { + assert(P2P_MODULE(win)->p2p_num_pending_in == 0); + assert(P2P_MODULE(win)->p2p_num_pending_out == 0); + OBJ_RETAIN(group); /* BWB - do I need this? */ ompi_group_increment_proc_count(group); OPAL_THREAD_LOCK(&(P2P_MODULE(win)->p2p_lock)); - if (NULL != P2P_MODULE(win)->p2p_sc_group || NULL != P2P_MODULE(win)->p2p_pw_group) { - OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock)); - return MPI_ERR_RMA_CONFLICT; - } + assert(NULL == P2P_MODULE(win)->p2p_sc_group); P2P_MODULE(win)->p2p_sc_group = group; OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock)); @@ -305,15 +305,15 @@ ompi_osc_pt2pt_module_post(ompi_group_t *group, { int i; + assert(P2P_MODULE(win)->p2p_num_pending_in == 0); + assert(P2P_MODULE(win)->p2p_num_pending_out == 0); + OBJ_RETAIN(group); /* BWB - do I need this? */ ompi_group_increment_proc_count(group); OPAL_THREAD_LOCK(&(P2P_MODULE(win)->p2p_lock)); - if (NULL != P2P_MODULE(win)->p2p_sc_group || NULL != P2P_MODULE(win)->p2p_pw_group) { - OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock)); - return MPI_ERR_RMA_CONFLICT; - } + assert(NULL == P2P_MODULE(win)->p2p_pw_group); P2P_MODULE(win)->p2p_pw_group = group; OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock)); diff --git a/ompi/mpi/c/accumulate.c b/ompi/mpi/c/accumulate.c index 532fb13a8d..f3942bf16b 100644 --- a/ompi/mpi/c/accumulate.c +++ b/ompi/mpi/c/accumulate.c @@ -58,7 +58,7 @@ int MPI_Accumulate(void *origin_addr, int origin_count, MPI_Datatype origin_data rc = MPI_ERR_RANK; } else if (MPI_OP_NULL == op) { rc = MPI_ERR_OP; - } else if (0 == (ompi_win_get_mode(win) & OMPI_WIN_ACCESS_EPOCH)) { + } else if (!ompi_win_comm_allowed(win)) { rc = MPI_ERR_RMA_CONFLICT; } else { OMPI_CHECK_DATATYPE_FOR_SEND(rc, origin_datatype, origin_count); diff --git a/ompi/mpi/c/get.c b/ompi/mpi/c/get.c index e5e83689dd..67850d84dd 100644 --- a/ompi/mpi/c/get.c +++ b/ompi/mpi/c/get.c @@ -53,7 +53,7 @@ int MPI_Get(void *origin_addr, int origin_count, rc = MPI_ERR_COUNT; } else if (ompi_win_peer_invalid(win, target_rank)) { rc = MPI_ERR_RANK; - } else if (0 == (ompi_win_get_mode(win) & OMPI_WIN_ACCESS_EPOCH)) { + } else if (!ompi_win_comm_allowed(win)) { rc = MPI_ERR_RMA_CONFLICT; } else { OMPI_CHECK_DATATYPE_FOR_SEND(rc, origin_datatype, origin_count); diff --git a/ompi/mpi/c/put.c b/ompi/mpi/c/put.c index bcd52a970d..d151963fc4 100644 --- a/ompi/mpi/c/put.c +++ b/ompi/mpi/c/put.c @@ -52,7 +52,7 @@ int MPI_Put(void *origin_addr, int origin_count, MPI_Datatype origin_datatype, rc = MPI_ERR_COUNT; } else if (ompi_win_peer_invalid(win, target_rank)) { rc = MPI_ERR_RANK; - } else if (0 == (ompi_win_get_mode(win) & OMPI_WIN_ACCESS_EPOCH)) { + } else if (!ompi_win_comm_allowed(win)) { rc = MPI_ERR_RMA_CONFLICT; } else { OMPI_CHECK_DATATYPE_FOR_SEND(rc, origin_datatype, origin_count); diff --git a/ompi/mpi/c/win_free.c b/ompi/mpi/c/win_free.c index d2a3aeb787..894b0759dc 100644 --- a/ompi/mpi/c/win_free.c +++ b/ompi/mpi/c/win_free.c @@ -34,22 +34,16 @@ static const char FUNC_NAME[] = "MPI_Win_free"; int MPI_Win_free(MPI_Win *win) { - int ret, mode; + int ret; if (MPI_PARAM_CHECK) { OMPI_ERR_INIT_FINALIZE(FUNC_NAME); if (ompi_win_invalid(*win)) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME); - } - - /* we allow users to be in an epoch, because that tends to - happen with people using MPI_FENCE. However, do not allow - users to be in a Lock / Unlock or a PWSC synchronization */ - mode = ompi_win_get_mode(*win); - if (0 != (mode & (OMPI_WIN_POSTED | OMPI_WIN_STARTED | - OMPI_WIN_LOCK_ACCESS))) { - return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, + } else if ((OMPI_WIN_ACCESS_EPOCH|OMPI_WIN_EXPOSE_EPOCH) & + ompi_win_get_mode(*win)) { + return OMPI_ERRHANDLER_INVOKE(*win, MPI_ERR_RMA_CONFLICT, FUNC_NAME); } diff --git a/ompi/mpi/c/win_lock.c b/ompi/mpi/c/win_lock.c index 296cc87d58..bcb4f369b6 100644 --- a/ompi/mpi/c/win_lock.c +++ b/ompi/mpi/c/win_lock.c @@ -49,9 +49,7 @@ int MPI_Win_lock(int lock_type, int rank, int assert, MPI_Win win) return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RANK, FUNC_NAME); } else if (0 != (assert & ~(MPI_MODE_NOCHECK))) { return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME); - } else if (0 != (ompi_win_get_mode(win) & - (OMPI_WIN_ACCESS_EPOCH | OMPI_WIN_EXPOSE_EPOCH))) { - /* can't be in either an access or exposure epoch (even a lock one)*/ + } else if (0 != (ompi_win_get_mode(win) & OMPI_WIN_ACCESS_EPOCH)) { return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME); } else if (! ompi_win_allow_locks(win)) { return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_SYNC, FUNC_NAME); diff --git a/ompi/mpi/c/win_post.c b/ompi/mpi/c/win_post.c index bcdcd8fa50..f2cef4a36f 100644 --- a/ompi/mpi/c/win_post.c +++ b/ompi/mpi/c/win_post.c @@ -45,10 +45,7 @@ int MPI_Win_post(MPI_Group group, int assert, MPI_Win win) } else if (0 != (assert & ~(MPI_MODE_NOCHECK | MPI_MODE_NOSTORE | MPI_MODE_NOPUT))) { return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME); - } else if (0 != (ompi_win_get_mode(win) & - (OMPI_WIN_ACCESS_EPOCH | OMPI_WIN_EXPOSE_EPOCH))) { - /* we can't already be in an an exposure or accesss epoch - when we start a post */ + } else if (0 != (ompi_win_get_mode(win) & OMPI_WIN_EXPOSE_EPOCH)) { return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME); } } diff --git a/ompi/mpi/c/win_start.c b/ompi/mpi/c/win_start.c index 25ba1d5ae7..d5f86a1d5a 100644 --- a/ompi/mpi/c/win_start.c +++ b/ompi/mpi/c/win_start.c @@ -44,10 +44,7 @@ int MPI_Win_start(MPI_Group group, int assert, MPI_Win win) return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_WIN, FUNC_NAME); } else if (0 != (assert & ~(MPI_MODE_NOCHECK))) { return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME); - } else if (0 != (ompi_win_get_mode(win) & - (OMPI_WIN_ACCESS_EPOCH | OMPI_WIN_EXPOSE_EPOCH))) { - /* we can't already be in an an exposure or accesss epoch - when we start a start */ + } else if (0 != (ompi_win_get_mode(win) & OMPI_WIN_ACCESS_EPOCH)) { return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME); } } diff --git a/ompi/win/win.h b/ompi/win/win.h index 4d9bc31bcb..b2e4c3107a 100644 --- a/ompi/win/win.h +++ b/ompi/win/win.h @@ -42,9 +42,10 @@ extern "C" { /* mode */ #define OMPI_WIN_ACCESS_EPOCH 0x00000001 #define OMPI_WIN_EXPOSE_EPOCH 0x00000002 -#define OMPI_WIN_POSTED 0x00000010 -#define OMPI_WIN_STARTED 0x00000020 -#define OMPI_WIN_LOCK_ACCESS 0x00000040 +#define OMPI_WIN_FENCE 0x00000010 +#define OMPI_WIN_POSTED 0x00000020 +#define OMPI_WIN_STARTED 0x00000040 +#define OMPI_WIN_LOCK_ACCESS 0x00000080 OMPI_DECLSPEC extern ompi_pointer_array_t ompi_mpi_windows; @@ -141,6 +142,20 @@ static inline void ompi_win_set_mode(ompi_win_t *win, int16_t mode) { opal_atomic_wmb(); } +/* already in an access epoch */ +static inline bool ompi_win_access_epoch(ompi_win_t *win) { + int16_t mode = ompi_win_get_mode(win); + return (OMPI_WIN_ACCESS_EPOCH & mode); +} + +/* we're either already in an access epoch or can easily start one + (stupid fence rule). Either way, it's ok to be the origin of a + communication call. */ +static inline bool ompi_win_comm_allowed(ompi_win_t *win) { + int16_t mode = ompi_win_get_mode(win); + return (OMPI_WIN_ACCESS_EPOCH & mode || OMPI_WIN_FENCE & mode); +} + #if defined(c_plusplus) || defined(__cplusplus) } #endif