int MPIDI_CH3I_RMA_Make_progress_target(MPIR_Win * win_ptr, int target_rank, int *made_progress) { int temp_progress = 0; int is_able_to_issue = 0; MPIDI_RMA_Target_t *target = NULL; int mpi_errno = MPI_SUCCESS; (*made_progress) = 0; /* NOTE: this function is called from either operation routines (MPI_PUT, MPI_GET...), * or aggressive cleanup functions. It cannot be called from the progress engine. * Here we poke the progress engine if window state is not satisfied (i.e. NBC is not * finished). If it is allowed to be called from progress engine, when RMA progress * is registered / executed before NBC progress, it will cause the progress engine * to re-entrant RMA progress endlessly. */ /* check window state, if it is not ready, poke the progress engine */ if (!WIN_READY(win_ptr)) { mpi_errno = poke_progress_engine(); if (mpi_errno) MPIR_ERR_POP(mpi_errno); goto fn_exit; } /* find target element */ mpi_errno = MPIDI_CH3I_Win_find_target(win_ptr, target_rank, &target); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); /* check and try to switch target state */ mpi_errno = check_and_switch_target_state(win_ptr, target, &is_able_to_issue, &temp_progress); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); if (temp_progress) (*made_progress) = 1; if (!is_able_to_issue) { mpi_errno = poke_progress_engine(); if (mpi_errno) MPIR_ERR_POP(mpi_errno); goto fn_exit; } /* issue operations to this target */ mpi_errno = issue_ops_target(win_ptr, target, &temp_progress); if (mpi_errno) MPIR_ERR_POP(mpi_errno); if (temp_progress) (*made_progress) = 1; fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIDI_CH3I_RMA_Make_progress_target(MPID_Win * win_ptr, int target_rank, int *made_progress) { int temp_progress = 0; MPIDI_RMA_Target_t *target = NULL; int mpi_errno = MPI_SUCCESS; (*made_progress) = 0; /* check window state */ mpi_errno = check_window_state(win_ptr, &temp_progress); if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno); if (temp_progress) (*made_progress) = 1; /* find target element */ mpi_errno = MPIDI_CH3I_Win_find_target(win_ptr, target_rank, &target); if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno); /* check target state */ mpi_errno = check_target_state(win_ptr, target, &temp_progress); if (mpi_errno) MPIU_ERR_POP(mpi_errno); if (temp_progress) (*made_progress) = 1; /* issue operations to this target */ mpi_errno = issue_ops_target(win_ptr, target, &temp_progress); if (mpi_errno) MPIU_ERR_POP(mpi_errno); if (temp_progress) (*made_progress) = 1; fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIDI_CH3I_RMA_Cleanup_target_aggressive(MPIR_Win * win_ptr, MPIDI_RMA_Target_t ** target) { int i, local_completed ATTRIBUTE((unused)) = 0, remote_completed = 0; int made_progress = 0; MPIDI_RMA_Target_t *curr_target = NULL; int mpi_errno = MPI_SUCCESS; (*target) = NULL; if (win_ptr->states.access_state == MPIDI_RMA_LOCK_ALL_CALLED) { /* switch to window-wide protocol */ MPIDI_VC_t *orig_vc = NULL, *target_vc = NULL; MPIDI_Comm_get_vc(win_ptr->comm_ptr, win_ptr->comm_ptr->rank, &orig_vc); for (i = 0; i < win_ptr->comm_ptr->local_size; i++) { if (i == win_ptr->comm_ptr->rank) continue; MPIDI_Comm_get_vc(win_ptr->comm_ptr, i, &target_vc); if (orig_vc->node_id != target_vc->node_id) { mpi_errno = MPIDI_CH3I_Win_find_target(win_ptr, i, &curr_target); if (mpi_errno) MPIR_ERR_POP(mpi_errno); if (curr_target == NULL) { win_ptr->outstanding_locks++; mpi_errno = send_lock_msg(i, MPI_LOCK_SHARED, win_ptr); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); } } } win_ptr->states.access_state = MPIDI_RMA_LOCK_ALL_ISSUED; } do { /* find a non-empty slot and set the FLUSH flag on the first * target */ /* TODO: we should think about better strategies on selecting the target */ for (i = 0; i < win_ptr->num_slots; i++) if (win_ptr->slots[i].target_list_head != NULL) break; curr_target = win_ptr->slots[i].target_list_head; if (curr_target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH) { curr_target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH; } /* Issue out all operations. */ mpi_errno = MPIDI_CH3I_RMA_Make_progress_target(win_ptr, curr_target->target_rank, &made_progress); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); /* Wait for remote completion. */ do { MPIDI_CH3I_RMA_ops_completion(win_ptr, curr_target, local_completed, remote_completed); if (!remote_completed) { mpi_errno = wait_progress_engine(); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); } } while (!remote_completed); /* Cleanup the target. */ mpi_errno = MPIDI_CH3I_Win_target_dequeue_and_free(win_ptr, curr_target); if (mpi_errno != MPI_SUCCESS) MPIR_ERR_POP(mpi_errno); /* check if we got a target */ (*target) = MPIDI_CH3I_Win_target_alloc(win_ptr); } while ((*target) == NULL); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }
int MPIDI_CH3I_RMA_Cleanup_target_aggressive(MPID_Win * win_ptr, MPIDI_RMA_Target_t ** target) { int i, local_completed = 0, remote_completed = 0; int made_progress = 0; MPIDI_RMA_Target_t *curr_target = NULL; int mpi_errno = MPI_SUCCESS; (*target) = NULL; /* If we are in an aggressive cleanup, the window must be holding * up resources. If it isn't, we are in the wrong window and * incorrectly entered this function. */ MPIU_ERR_CHKANDJUMP(win_ptr->non_empty_slots == 0, mpi_errno, MPI_ERR_OTHER, "**rmanotarget"); if (win_ptr->states.access_state == MPIDI_RMA_LOCK_ALL_CALLED) { /* switch to window-wide protocol */ MPIDI_VC_t *orig_vc = NULL, *target_vc = NULL; MPIDI_Comm_get_vc(win_ptr->comm_ptr, win_ptr->comm_ptr->rank, &orig_vc); for (i = 0; i < win_ptr->comm_ptr->local_size; i++) { if (i == win_ptr->comm_ptr->rank) continue; MPIDI_Comm_get_vc(win_ptr->comm_ptr, i, &target_vc); if (orig_vc->node_id != target_vc->node_id) { mpi_errno = MPIDI_CH3I_Win_find_target(win_ptr, i, &curr_target); if (mpi_errno) MPIU_ERR_POP(mpi_errno); if (curr_target == NULL) { win_ptr->outstanding_locks++; mpi_errno = send_lock_msg(i, MPI_LOCK_SHARED, win_ptr); if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno); } } } win_ptr->states.access_state = MPIDI_RMA_LOCK_ALL_ISSUED; } do { /* find a non-empty slot and set the FLUSH flag on the first * target */ /* TODO: we should think about better strategies on selecting the target */ for (i = 0; i < win_ptr->num_slots; i++) if (win_ptr->slots[i].target_list != NULL) break; curr_target = win_ptr->slots[i].target_list; if (curr_target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH) { curr_target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH; curr_target->sync.have_remote_incomplete_ops = 0; curr_target->sync.outstanding_acks++; } /* Issue out all operations. */ mpi_errno = MPIDI_CH3I_RMA_Make_progress_target(win_ptr, curr_target->target_rank, &made_progress); if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno); /* Wait for remote completion. */ do { mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_target(win_ptr, curr_target, &local_completed, &remote_completed); if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno); if (!remote_completed) { mpi_errno = wait_progress_engine(); if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno); } } while (!remote_completed); /* Cleanup the target. */ mpi_errno = MPIDI_CH3I_RMA_Cleanup_single_target(win_ptr, curr_target); if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno); /* check if we got a target */ (*target) = MPIDI_CH3I_Win_target_alloc(win_ptr); } while ((*target) == NULL); fn_exit: return mpi_errno; fn_fail: goto fn_exit; }