Пример #1
0
/* 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;
}
Пример #2
0
/* 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;
}