Commit aa36f043 authored by Xin Zhao's avatar Xin Zhao
Browse files

Fix completion on target side in Active Target synchronization.



For Active Target synchronization, the original implementation
does not guarantee the completion of all ops on target side
when Win_wait / Win_fence returns. It is implemented using a
counter, which is decremented when the last operation from that
origin finishes. Win_wait / Win_fence waits until that counter
reaches zero. Problem is that, when the last operation finishes,
the previous GET-like operation (for example with a large data
volume) may have not finished yet. This breaks the semantic of
Win_wait / Win_fence.

Here we fix this by increment the counter whenever we meet a
GET-like operation, and decrement it when that operation finishes
on target side. This will guarantee that when counter reaches
zero and Win_wait / Win_fence returns, all operations are completed
on the target.
Signed-off-by: Pavan Balaji's avatarPavan Balaji <balaji@anl.gov>
parent 32596b62
......@@ -82,6 +82,7 @@ int MPIDI_CH3_ReqHandler_PutAccumRespComplete( MPIDI_VC_t *vc,
int *complete )
{
int mpi_errno = MPI_SUCCESS;
int get_acc_flag = 0;
MPID_Win *win_ptr;
MPIU_CHKPMEM_DECL(1);
MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_REQHANDLER_PUTACCUMRESPCOMPLETE);
......@@ -139,6 +140,8 @@ int MPIDI_CH3_ReqHandler_PutAccumRespComplete( MPIDI_VC_t *vc,
/* Mark get portion as handled */
rreq->dev.resp_request_handle = MPI_REQUEST_NULL;
get_acc_flag = 1;
}
MPID_Win_get_ptr(rreq->dev.target_win_handle, win_ptr);
......@@ -161,6 +164,13 @@ int MPIDI_CH3_ReqHandler_PutAccumRespComplete( MPIDI_VC_t *vc,
rreq->dev.source_win_handle);
if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
if (get_acc_flag) {
/* here we decrement the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter--;
MPIU_Assert(win_ptr->my_counter >= 0);
}
/* mark data transfer as complete and decrement CC */
MPIDI_CH3U_Request_complete(rreq);
*complete = TRUE;
......@@ -571,6 +581,11 @@ int MPIDI_CH3_ReqHandler_FOPComplete( MPIDI_VC_t *vc,
rreq->dev.source_win_handle);
if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
/* here we decrement the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter--;
MPIU_Assert(win_ptr->my_counter >= 0);
*complete = 1;
fn_exit:
......@@ -1189,6 +1204,10 @@ static int do_simple_get(MPID_Win *win_ptr, MPIDI_Win_lock_queue *lock_queue)
req->kind = MPID_REQUEST_SEND;
req->dev.OnDataAvail = MPIDI_CH3_ReqHandler_GetSendRespComplete;
req->dev.OnFinal = MPIDI_CH3_ReqHandler_GetSendRespComplete;
/* here we increment the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter++;
MPIDI_Pkt_init(get_resp_pkt, MPIDI_CH3_PKT_GET_RESP);
get_resp_pkt->request_handle = lock_queue->pt_single_op->request_handle;
......
......@@ -55,6 +55,11 @@ int MPIDI_CH3_ReqHandler_GetSendRespComplete( MPIDI_VC_t *vc ATTRIBUTE((unused))
mpi_errno = MPIDI_CH3_Finish_rma_op_target(NULL, win_ptr, FALSE, sreq->dev.flags, MPI_WIN_NULL);
if (mpi_errno) { MPIU_ERR_POP(mpi_errno); }
/* here we decrement the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter--;
MPIU_Assert(win_ptr->my_counter >= 0);
/* mark data transfer as complete and decrement CC */
MPIDI_CH3U_Request_complete(sreq);
*complete = TRUE;
......
......@@ -1269,7 +1269,7 @@ int MPIDI_Win_fence(int assert, MPID_Win *win_ptr)
RMA ops on its window */
/* first initialize the completion counter. */
win_ptr->my_counter = comm_size;
win_ptr->my_counter += comm_size;
mpi_errno = MPIR_Reduce_scatter_block_impl(MPI_IN_PLACE, rma_target_proc, 1,
MPI_INT, MPI_SUM, comm_ptr, &errflag);
......@@ -1286,8 +1286,8 @@ int MPIDI_Win_fence(int assert, MPID_Win *win_ptr)
/* Set the completion counter */
/* FIXME: MT: this needs to be done atomically because other
procs have the address and could decrement it. */
win_ptr->my_counter = win_ptr->my_counter - comm_size +
rma_target_proc[0];
win_ptr->my_counter -= comm_size;
win_ptr->my_counter += rma_target_proc[0];
MPIR_T_PVAR_TIMER_START(RMA, rma_winfence_issue);
MPIR_T_PVAR_COUNTER_INC(RMA, rma_winfence_issue_aux, total_op_count);
......@@ -2292,7 +2292,7 @@ int MPIDI_Win_post(MPID_Group *post_grp_ptr, int assert, MPID_Win *win_ptr)
}
/* initialize the completion counter */
win_ptr->my_counter = post_grp_size;
win_ptr->my_counter += post_grp_size;
if ((assert & MPI_MODE_NOCHECK) == 0)
{
......@@ -4600,6 +4600,10 @@ int MPIDI_CH3_PktHandler_Get( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt,
req->dev.target_win_handle = get_pkt->target_win_handle;
req->dev.source_win_handle = get_pkt->source_win_handle;
req->dev.flags = get_pkt->flags;
/* here we increment the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter++;
if (MPIR_DATATYPE_IS_PREDEFINED(get_pkt->datatype))
{
......@@ -4733,6 +4737,12 @@ int MPIDI_CH3_PktHandler_Accumulate( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt,
req = MPID_Request_create();
MPIU_Object_set_ref(req, 1);
*rreqp = req;
if (accum_pkt->type == MPIDI_CH3_PKT_GET_ACCUM) {
/* here we increment the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter++;
}
req->dev.user_count = accum_pkt->count;
req->dev.op = accum_pkt->op;
......@@ -5086,6 +5096,10 @@ int MPIDI_CH3_PktHandler_FOP( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt,
MPIU_Object_set_ref(req, 1); /* Ref is held by progress engine */
*rreqp = NULL;
/* here we increment the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter++;
req->dev.user_buf = NULL; /* will be set later */
req->dev.user_count = 1;
req->dev.datatype = fop_pkt->datatype;
......@@ -5511,6 +5525,10 @@ int MPIDI_CH3_PktHandler_LockGetUnlock( MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t *pkt,
req->dev.OnDataAvail = MPIDI_CH3_ReqHandler_GetSendRespComplete;
req->dev.OnFinal = MPIDI_CH3_ReqHandler_GetSendRespComplete;
req->kind = MPID_REQUEST_SEND;
/* here we increment the Active Target counter to guarantee the GET-like
operation are completed when counter reaches zero. */
win_ptr->my_counter++;
MPIDI_Pkt_init(get_resp_pkt, MPIDI_CH3_PKT_GET_RESP);
get_resp_pkt->request_handle = lock_get_unlock_pkt->request_handle;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment