/* progresses a request * * to be called *only* from the progress thread !!! */ int NBC_Progress(NBC_Handle *handle) { int flag, res, ret=NBC_CONTINUE; unsigned long size; char *delim; /* the handle is done if there is no schedule attached */ if (NULL == handle->schedule) { return NBC_OK; } if ((handle->req_count > 0) && (handle->req_array != NULL)) { NBC_DEBUG(50, "NBC_Progress: testing for %i requests\n", handle->req_count); #ifdef NBC_TIMING Test_time -= MPI_Wtime(); #endif res = ompi_request_test_all(handle->req_count, handle->req_array, &flag, MPI_STATUSES_IGNORE); if(res != OMPI_SUCCESS) { NBC_Error ("MPI Error in MPI_Testall() (%i)", res); return res; } #ifdef NBC_TIMING Test_time += MPI_Wtime(); #endif } else { flag = 1; /* we had no open requests -> proceed to next round */ } /* a round is finished */ if (flag) { /* adjust delim to start of current round */ NBC_DEBUG(5, "NBC_Progress: going in schedule %p to row-offset: %li\n", handle->schedule, handle->row_offset); delim = handle->schedule->data + handle->row_offset; NBC_DEBUG(10, "delim: %p\n", delim); nbc_get_round_size(delim, &size); NBC_DEBUG(10, "size: %li\n", size); /* adjust delim to end of current round -> delimiter */ delim = delim + size; if (NULL != handle->req_array) { /* free request array */ free (handle->req_array); handle->req_array = NULL; } handle->req_count = 0; if (*delim == 0) { /* this was the last round - we're done */ NBC_DEBUG(5, "NBC_Progress last round finished - we're done\n"); NBC_Free(handle); return NBC_OK; } NBC_DEBUG(5, "NBC_Progress round finished - goto next round\n"); /* move delim to start of next round */ /* initializing handle for new virgin round */ handle->row_offset = (intptr_t) (delim + 1) - (intptr_t) handle->schedule->data; /* kick it off */ res = NBC_Start_round(handle); if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) { NBC_Error ("Error in NBC_Start_round() (%i)", res); return res; } } return ret; }
/* progresses a request * * to be called *only* from the progress thread !!! */ int NBC_Progress(NBC_Handle *handle) { int res, ret=NBC_CONTINUE; bool flag; unsigned long size = 0; char *delim; if (handle->nbc_complete) { return NBC_OK; } flag = true; if ((handle->req_count > 0) && (handle->req_array != NULL)) { NBC_DEBUG(50, "NBC_Progress: testing for %i requests\n", handle->req_count); #ifdef NBC_TIMING Test_time -= MPI_Wtime(); #endif /* don't call ompi_request_test_all as it causes a recursive call into opal_progress */ while (handle->req_count) { ompi_request_t *subreq = handle->req_array[handle->req_count - 1]; if (REQUEST_COMPLETE(subreq)) { if(OPAL_UNLIKELY( OMPI_SUCCESS != subreq->req_status.MPI_ERROR )) { NBC_Error ("MPI Error in NBC subrequest %p : %d", subreq, subreq->req_status.MPI_ERROR); /* copy the error code from the underlying request and let the * round finish */ handle->super.req_status.MPI_ERROR = subreq->req_status.MPI_ERROR; } handle->req_count--; ompi_request_free(&subreq); } else { flag = false; break; } } #ifdef NBC_TIMING Test_time += MPI_Wtime(); #endif } /* a round is finished */ if (flag) { /* reset handle for next round */ if (NULL != handle->req_array) { /* free request array */ free (handle->req_array); handle->req_array = NULL; } handle->req_count = 0; /* previous round had an error */ if (OPAL_UNLIKELY(OMPI_SUCCESS != handle->super.req_status.MPI_ERROR)) { res = handle->super.req_status.MPI_ERROR; NBC_Error("NBC_Progress: an error %d was found during schedule %p at row-offset %li - aborting the schedule\n", res, handle->schedule, handle->row_offset); handle->nbc_complete = true; if (!handle->super.req_persistent) { NBC_Free(handle); } return res; } /* adjust delim to start of current round */ NBC_DEBUG(5, "NBC_Progress: going in schedule %p to row-offset: %li\n", handle->schedule, handle->row_offset); delim = handle->schedule->data + handle->row_offset; NBC_DEBUG(10, "delim: %p\n", delim); nbc_get_round_size(delim, &size); NBC_DEBUG(10, "size: %li\n", size); /* adjust delim to end of current round -> delimiter */ delim = delim + size; if (*delim == 0) { /* this was the last round - we're done */ NBC_DEBUG(5, "NBC_Progress last round finished - we're done\n"); handle->nbc_complete = true; if (!handle->super.req_persistent) { NBC_Free(handle); } return NBC_OK; } NBC_DEBUG(5, "NBC_Progress round finished - goto next round\n"); /* move delim to start of next round */ /* initializing handle for new virgin round */ handle->row_offset = (intptr_t) (delim + 1) - (intptr_t) handle->schedule->data; /* kick it off */ res = NBC_Start_round(handle); if (OPAL_UNLIKELY(OMPI_SUCCESS != res)) { NBC_Error ("Error in NBC_Start_round() (%i)", res); return res; } } return ret; }