1
1

* 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.
Этот коммит содержится в:
Brian Barrett 2006-02-24 13:04:15 +00:00
родитель 27b8430e8f
Коммит d5e0ea3590
11 изменённых файлов: 57 добавлений и 44 удалений

Просмотреть файл

@ -33,13 +33,6 @@ ompi_osc_pt2pt_module_free(ompi_win_t *win)
int tmp; int tmp;
ompi_osc_pt2pt_module_t *module = P2P_MODULE(win); 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 */ /* finish with a barrier */
if (ompi_group_size(win->w_group) > 1) { if (ompi_group_size(win->w_group) > 1) {
ret = module->p2p_comm->c_coll.coll_barrier(module->p2p_comm); 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; int ret;
ompi_osc_pt2pt_sendreq_t *sendreq; 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, "MPI_Accumulate currently does not support reductions\n");
fprintf(stderr, "with any user-defined types. This will be rectified\n"); fprintf(stderr, "with any user-defined types. This will be rectified\n");
fprintf(stderr, "in a future release.\n"); fprintf(stderr, "in a future release.\n");
@ -89,6 +96,12 @@ ompi_osc_pt2pt_module_get(void *origin_addr,
int ret; int ret;
ompi_osc_pt2pt_sendreq_t *sendreq; 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 */ /* create sendreq */
ret = ompi_osc_pt2pt_sendreq_alloc_init(OMPI_OSC_PT2PT_GET, ret = ompi_osc_pt2pt_sendreq_alloc_init(OMPI_OSC_PT2PT_GET,
origin_addr, origin_addr,
@ -118,6 +131,12 @@ ompi_osc_pt2pt_module_put(void *origin_addr, int origin_count,
int ret; int ret;
ompi_osc_pt2pt_sendreq_t *sendreq; 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 */ /* create sendreq */
ret = ompi_osc_pt2pt_sendreq_alloc_init(OMPI_OSC_PT2PT_PUT, ret = ompi_osc_pt2pt_sendreq_alloc_init(OMPI_OSC_PT2PT_PUT,
origin_addr, 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 */ /* all transfers are done - back to the real world we go */
if (0 == (assert & MPI_MODE_NOSUCCEED)) { 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 { } else {
ompi_win_set_mode(win, 0); ompi_win_set_mode(win, 0);
} }
@ -189,15 +189,15 @@ ompi_osc_pt2pt_module_start(ompi_group_t *group,
int assert, int assert,
ompi_win_t *win) 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); OBJ_RETAIN(group);
/* BWB - do I need this? */ /* BWB - do I need this? */
ompi_group_increment_proc_count(group); ompi_group_increment_proc_count(group);
OPAL_THREAD_LOCK(&(P2P_MODULE(win)->p2p_lock)); OPAL_THREAD_LOCK(&(P2P_MODULE(win)->p2p_lock));
if (NULL != P2P_MODULE(win)->p2p_sc_group || NULL != P2P_MODULE(win)->p2p_pw_group) { assert(NULL == P2P_MODULE(win)->p2p_sc_group);
OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock));
return MPI_ERR_RMA_CONFLICT;
}
P2P_MODULE(win)->p2p_sc_group = group; P2P_MODULE(win)->p2p_sc_group = group;
OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock)); OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock));
@ -305,15 +305,15 @@ ompi_osc_pt2pt_module_post(ompi_group_t *group,
{ {
int i; int i;
assert(P2P_MODULE(win)->p2p_num_pending_in == 0);
assert(P2P_MODULE(win)->p2p_num_pending_out == 0);
OBJ_RETAIN(group); OBJ_RETAIN(group);
/* BWB - do I need this? */ /* BWB - do I need this? */
ompi_group_increment_proc_count(group); ompi_group_increment_proc_count(group);
OPAL_THREAD_LOCK(&(P2P_MODULE(win)->p2p_lock)); OPAL_THREAD_LOCK(&(P2P_MODULE(win)->p2p_lock));
if (NULL != P2P_MODULE(win)->p2p_sc_group || NULL != P2P_MODULE(win)->p2p_pw_group) { assert(NULL == P2P_MODULE(win)->p2p_pw_group);
OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock));
return MPI_ERR_RMA_CONFLICT;
}
P2P_MODULE(win)->p2p_pw_group = group; P2P_MODULE(win)->p2p_pw_group = group;
OPAL_THREAD_UNLOCK(&(P2P_MODULE(win)->p2p_lock)); 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; rc = MPI_ERR_RANK;
} else if (MPI_OP_NULL == op) { } else if (MPI_OP_NULL == op) {
rc = MPI_ERR_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; rc = MPI_ERR_RMA_CONFLICT;
} else { } else {
OMPI_CHECK_DATATYPE_FOR_SEND(rc, origin_datatype, origin_count); 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; rc = MPI_ERR_COUNT;
} else if (ompi_win_peer_invalid(win, target_rank)) { } else if (ompi_win_peer_invalid(win, target_rank)) {
rc = MPI_ERR_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; rc = MPI_ERR_RMA_CONFLICT;
} else { } else {
OMPI_CHECK_DATATYPE_FOR_SEND(rc, origin_datatype, origin_count); 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; rc = MPI_ERR_COUNT;
} else if (ompi_win_peer_invalid(win, target_rank)) { } else if (ompi_win_peer_invalid(win, target_rank)) {
rc = MPI_ERR_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; rc = MPI_ERR_RMA_CONFLICT;
} else { } else {
OMPI_CHECK_DATATYPE_FOR_SEND(rc, origin_datatype, origin_count); 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 MPI_Win_free(MPI_Win *win)
{ {
int ret, mode; int ret;
if (MPI_PARAM_CHECK) { if (MPI_PARAM_CHECK) {
OMPI_ERR_INIT_FINALIZE(FUNC_NAME); OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
if (ompi_win_invalid(*win)) { if (ompi_win_invalid(*win)) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME); return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_WIN, FUNC_NAME);
} } else if ((OMPI_WIN_ACCESS_EPOCH|OMPI_WIN_EXPOSE_EPOCH) &
ompi_win_get_mode(*win)) {
/* we allow users to be in an epoch, because that tends to return OMPI_ERRHANDLER_INVOKE(*win,
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,
MPI_ERR_RMA_CONFLICT, MPI_ERR_RMA_CONFLICT,
FUNC_NAME); 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); return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RANK, FUNC_NAME);
} else if (0 != (assert & ~(MPI_MODE_NOCHECK))) { } else if (0 != (assert & ~(MPI_MODE_NOCHECK))) {
return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME); return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME);
} else if (0 != (ompi_win_get_mode(win) & } else if (0 != (ompi_win_get_mode(win) & OMPI_WIN_ACCESS_EPOCH)) {
(OMPI_WIN_ACCESS_EPOCH | OMPI_WIN_EXPOSE_EPOCH))) {
/* can't be in either an access or exposure epoch (even a lock one)*/
return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME); return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME);
} else if (! ompi_win_allow_locks(win)) { } else if (! ompi_win_allow_locks(win)) {
return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_SYNC, FUNC_NAME); 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 | } else if (0 != (assert & ~(MPI_MODE_NOCHECK | MPI_MODE_NOSTORE |
MPI_MODE_NOPUT))) { MPI_MODE_NOPUT))) {
return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME); return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME);
} else if (0 != (ompi_win_get_mode(win) & } else if (0 != (ompi_win_get_mode(win) & OMPI_WIN_EXPOSE_EPOCH)) {
(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 */
return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME); 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); return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_WIN, FUNC_NAME);
} else if (0 != (assert & ~(MPI_MODE_NOCHECK))) { } else if (0 != (assert & ~(MPI_MODE_NOCHECK))) {
return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME); return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_ASSERT, FUNC_NAME);
} else if (0 != (ompi_win_get_mode(win) & } else if (0 != (ompi_win_get_mode(win) & OMPI_WIN_ACCESS_EPOCH)) {
(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 */
return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME); return OMPI_ERRHANDLER_INVOKE(win, MPI_ERR_RMA_CONFLICT, FUNC_NAME);
} }
} }

Просмотреть файл

@ -42,9 +42,10 @@ extern "C" {
/* mode */ /* mode */
#define OMPI_WIN_ACCESS_EPOCH 0x00000001 #define OMPI_WIN_ACCESS_EPOCH 0x00000001
#define OMPI_WIN_EXPOSE_EPOCH 0x00000002 #define OMPI_WIN_EXPOSE_EPOCH 0x00000002
#define OMPI_WIN_POSTED 0x00000010 #define OMPI_WIN_FENCE 0x00000010
#define OMPI_WIN_STARTED 0x00000020 #define OMPI_WIN_POSTED 0x00000020
#define OMPI_WIN_LOCK_ACCESS 0x00000040 #define OMPI_WIN_STARTED 0x00000040
#define OMPI_WIN_LOCK_ACCESS 0x00000080
OMPI_DECLSPEC extern ompi_pointer_array_t ompi_mpi_windows; 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(); 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) #if defined(c_plusplus) || defined(__cplusplus)
} }
#endif #endif