* 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.
Этот коммит содержится в:
родитель
27b8430e8f
Коммит
d5e0ea3590
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user