Commit 5dd55154 authored by Xin Zhao's avatar Xin Zhao
Browse files

Implement GET_OP routine which guarantees to return an OP.



GET_OP function may be a blocking function which guarantees
to return an RMA operation.

Inside GET_OP we first call the normal OP_ALLOC function
which will try to get a new OP from OP pools; if failed,
we call nonblocking GC function to cleanup completed ops
and then call OP_ALLOC again; if we still cannot get a
new OP, we call nonblocking FREE_OP_BEFORE_COMPLETION
function if hardware ordering is provided and then call
OP_ALLOC again; if still failed, finally we call blocking
aggressive cleanup function, which will guarantee to
return a new OP element.
Signed-off-by: Pavan Balaji's avatarPavan Balaji <balaji@anl.gov>
parent 7c1e12f0
......@@ -517,6 +517,49 @@ static inline int MPIDI_CH3I_RMA_Cleanup_targets_win(MPID_Win *win_ptr)
goto fn_exit;
}
#undef FUNCNAME
#define FUNCNAME MPIDI_CH3I_Win_get_op
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
static inline int MPIDI_CH3I_Win_get_op(MPID_Win * win_ptr, MPIDI_RMA_Op_t **e)
{
MPIDI_RMA_Op_t *new_ptr = NULL;
int local_completed = 0, remote_completed = 0;
int mpi_errno = MPI_SUCCESS;
while (1) {
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr != NULL) break;
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_win(win_ptr,
&local_completed,
&remote_completed);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr != NULL) break;
if (MPIDI_RMA_Pkt_orderings->flush_remote) {
mpi_errno = MPIDI_CH3I_RMA_Free_ops_before_completion(win_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr != NULL) break;
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
(*e) = new_ptr;
fn_exit:
return mpi_errno;
fn_fail:
goto fn_exit;
}
/* Return nonzero if the RMA operations list is empty.
*/
#undef FUNCNAME
......@@ -586,11 +629,8 @@ static inline int MPIDI_CH3I_RMA_Ops_alloc_tail(MPID_Win * win_ptr, MPIDI_RMA_Op
int mpi_errno = MPI_SUCCESS;
MPIDI_RMA_Op_t *tmp_ptr;
tmp_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (tmp_ptr == NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr, &tmp_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
mpi_errno = MPIDI_CH3I_Win_get_op(win_ptr, &tmp_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
MPL_LL_APPEND(*list, *list_tail, tmp_ptr);
......
......@@ -303,6 +303,14 @@ struct MPIDI_Win_info_args {
struct MPIDI_RMA_op; /* forward decl from mpidrma.h */
typedef struct MPIDI_RMA_Pkt_orderings {
int flush_remote; /* ordered FLUSH, for remote completion */
/* FIXME: in future we should also add local completin
ordering: WAW, WAR, RAW, RAR. */
} MPIDI_RMA_Pkt_orderings_t;
extern MPIDI_RMA_Pkt_orderings_t *MPIDI_RMA_Pkt_orderings;
struct MPIDI_Win_target_state {
struct MPIDI_RMA_Op *rma_ops_list;
/* List of outstanding RMA operations */
......
......@@ -72,11 +72,8 @@ int MPIDI_Put(const void *origin_addr, int origin_count, MPI_Datatype
MPIDI_CH3_Pkt_put_t *put_pkt = NULL;
/* queue it up */
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr == NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
mpi_errno = MPIDI_CH3I_Win_get_op(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
put_pkt = &(new_ptr->pkt.put);
MPIDI_Pkt_init(put_pkt, MPIDI_CH3_PKT_PUT);
......@@ -185,11 +182,8 @@ int MPIDI_Get(void *origin_addr, int origin_count, MPI_Datatype
MPIDI_CH3_Pkt_get_t *get_pkt = NULL;
/* queue it up */
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr == NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
mpi_errno = MPIDI_CH3I_Win_get_op(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
get_pkt = &(new_ptr->pkt.get);
MPIDI_Pkt_init(get_pkt, MPIDI_CH3_PKT_GET);
......@@ -299,11 +293,8 @@ int MPIDI_Accumulate(const void *origin_addr, int origin_count, MPI_Datatype
MPIDI_CH3_Pkt_accum_t *accum_pkt = NULL;
/* queue it up */
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr == NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
mpi_errno = MPIDI_CH3I_Win_get_op(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
/* If predefined and contiguous, use a simplified element */
if (MPIR_DATATYPE_IS_PREDEFINED(origin_datatype) &&
......@@ -450,11 +441,8 @@ int MPIDI_Get_accumulate(const void *origin_addr, int origin_count,
MPIDI_RMA_Op_t *new_ptr = NULL;
/* Append the operation to the window's RMA ops queue */
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr == NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
mpi_errno = MPIDI_CH3I_Win_get_op(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
/* TODO: Can we use the MPIDI_RMA_ACC_CONTIG optimization? */
......@@ -589,11 +577,8 @@ int MPIDI_Compare_and_swap(const void *origin_addr, const void *compare_addr,
MPIDI_CH3_Pkt_cas_t *cas_pkt = NULL;
/* Append this operation to the RMA ops queue */
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr == NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
mpi_errno = MPIDI_CH3I_Win_get_op(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
cas_pkt = &(new_ptr->pkt.cas);
MPIDI_Pkt_init(cas_pkt, MPIDI_CH3_PKT_CAS);
......@@ -684,11 +669,8 @@ int MPIDI_Fetch_and_op(const void *origin_addr, void *result_addr,
MPIDI_CH3_Pkt_fop_t *fop_pkt = NULL;
/* Append this operation to the RMA ops queue */
new_ptr = MPIDI_CH3I_Win_op_alloc(win_ptr);
if (new_ptr == NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_aggressive(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
}
mpi_errno = MPIDI_CH3I_Win_get_op(win_ptr, &new_ptr);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
fop_pkt = &(new_ptr->pkt.fop);
MPIDI_Pkt_init(fop_pkt, MPIDI_CH3_PKT_FOP);
......
......@@ -65,6 +65,7 @@ cvars:
struct MPIDI_RMA_Op *global_rma_op_pool = NULL, *global_rma_op_pool_tail = NULL, *global_rma_op_pool_start = NULL;
struct MPIDI_RMA_Target *global_rma_target_pool = NULL, *global_rma_target_pool_tail = NULL, *global_rma_target_pool_start = NULL;
struct MPIDI_RMA_Pkt_orderings *MPIDI_RMA_Pkt_orderings = NULL;
#undef FUNCNAME
#define FUNCNAME MPIDI_RMA_init
......@@ -74,7 +75,7 @@ int MPIDI_RMA_init(void)
{
int mpi_errno = MPI_SUCCESS;
int i;
MPIU_CHKPMEM_DECL(2);
MPIU_CHKPMEM_DECL(3);
MPIDI_STATE_DECL(MPID_STATE_MPIDI_RMA_INIT);
......@@ -96,6 +97,13 @@ int MPIDI_RMA_init(void)
MPL_LL_APPEND(global_rma_target_pool, global_rma_target_pool_tail, &(global_rma_target_pool_start[i]));
}
MPIU_CHKPMEM_MALLOC(MPIDI_RMA_Pkt_orderings, struct MPIDI_RMA_Pkt_orderings *,
sizeof(struct MPIDI_RMA_Pkt_orderings),
mpi_errno, "RMA packet orderings");
/* FIXME: here we should let channel to set ordering flags. For now we just set them
in CH3 layer. */
MPIDI_RMA_Pkt_orderings->flush_remote = 1;
fn_exit:
MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_RMA_INIT);
return mpi_errno;
......@@ -118,6 +126,7 @@ void MPIDI_RMA_finalize(void)
MPIU_Free(global_rma_op_pool_start);
MPIU_Free(global_rma_target_pool_start);
MPIU_Free(MPIDI_RMA_Pkt_orderings);
MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_RMA_FINALIZE);
}
......
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