root/ompi/request/req_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ompi_request_default_test
  2. ompi_request_default_test_any
  3. ompi_request_default_test_all
  4. ompi_request_default_test_some

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2016 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2006-2008 Cisco Systems, Inc.  All rights reserved.
  14  * Copyright (c) 2010-2012 Oracle and/or its affiliates.  All rights reserved.
  15  * Copyright (c) 2012      Oak Ridge National Labs.  All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include "ompi_config.h"
  24 #include "ompi/constants.h"
  25 #include "ompi/request/request.h"
  26 #include "ompi/request/request_default.h"
  27 #include "ompi/request/grequest.h"
  28 
  29 #include "ompi/mca/crcp/crcp.h"
  30 
  31 int ompi_request_default_test(ompi_request_t ** rptr,
  32                               int *completed,
  33                               ompi_status_public_t * status )
  34 {
  35     ompi_request_t *request = *rptr;
  36 
  37 #if OPAL_ENABLE_PROGRESS_THREADS == 0
  38     int do_it_once = 0;
  39 
  40  recheck_request_status:
  41 #endif
  42     opal_atomic_mb();
  43     if( request->req_state == OMPI_REQUEST_INACTIVE ) {
  44         *completed = true;
  45         if (MPI_STATUS_IGNORE != status) {
  46             *status = ompi_status_empty;
  47         }
  48         return OMPI_SUCCESS;
  49     }
  50 
  51     if( REQUEST_COMPLETE(request) ) {
  52 #if OPAL_ENABLE_FT_CR == 1
  53         if( opal_cr_is_enabled) {
  54             OMPI_CRCP_REQUEST_COMPLETE(request);
  55         }
  56 #endif
  57 
  58         *completed = true;
  59         /* For a generalized request, we *have* to call the query_fn
  60            if it completes, even if the user provided
  61            STATUS_IGNORE.  See MPI-2:8.2. */
  62         if (OMPI_REQUEST_GEN == request->req_type) {
  63             ompi_grequest_invoke_query(request, &request->req_status);
  64             if (MPI_STATUS_IGNORE != status) {
  65                 int old_error = status->MPI_ERROR;
  66                 *status = request->req_status;
  67                 status->MPI_ERROR = old_error;
  68             }
  69         } else if (MPI_STATUS_IGNORE != status) {
  70             /* Do *NOT* set a new value for status->MPI_ERROR here!
  71                See MPI-1.1 doc, sec 3.2.5, p.22 */
  72             int old_error = status->MPI_ERROR;
  73             *status = request->req_status;
  74             status->MPI_ERROR = old_error;
  75         }
  76         if( request->req_persistent ) {
  77             request->req_state = OMPI_REQUEST_INACTIVE;
  78             return request->req_status.MPI_ERROR;
  79         }
  80         /* If there was an error, don't free the request -- just
  81            return the single error. */
  82         if (MPI_SUCCESS != request->req_status.MPI_ERROR) {
  83             return request->req_status.MPI_ERROR;
  84         }
  85         /* If there's an error on the request, assume that the request
  86            is still there.  Otherwise, Bad Things will happen
  87            later! */
  88         return ompi_request_free(rptr);
  89     }
  90 #if OPAL_ENABLE_PROGRESS_THREADS == 0
  91     if( 0 == do_it_once ) {
  92         /**
  93          * If we run the opal_progress then check the status of the request before
  94          * leaving. We will call the opal_progress only once per call.
  95          */
  96         opal_progress();
  97         do_it_once++;
  98         goto recheck_request_status;
  99     }
 100 #endif
 101     *completed = false;
 102     return OMPI_SUCCESS;
 103 }
 104 
 105 int ompi_request_default_test_any(
 106     size_t count,
 107     ompi_request_t ** requests,
 108     int *index,
 109     int *completed,
 110     ompi_status_public_t * status)
 111 {
 112     size_t i;
 113     size_t num_requests_null_inactive = 0;
 114     ompi_request_t **rptr;
 115     ompi_request_t *request;
 116 
 117     opal_atomic_mb();
 118     rptr = requests;
 119     for (i = 0; i < count; i++, rptr++) {
 120         request = *rptr;
 121         if( request->req_state == OMPI_REQUEST_INACTIVE ) {
 122             num_requests_null_inactive++;
 123             continue;
 124         }
 125 
 126         if( REQUEST_COMPLETE(request) ) {
 127 #if OPAL_ENABLE_FT_CR == 1
 128             if( opal_cr_is_enabled) {
 129                 OMPI_CRCP_REQUEST_COMPLETE(request);
 130             }
 131 #endif
 132 
 133             *index = i;
 134             *completed = true;
 135             /* MPI 2:8.2 says that generalized requests always have
 136                the query function invoked in TEST* / WAIT*
 137                (#@$%@#$%!!! Would have been simpler to call it in
 138                GREQUEST_COMPLETE!), even if the user passed in
 139                STATUS_IGNORE */
 140             if (OMPI_REQUEST_GEN == request->req_type) {
 141                 ompi_grequest_invoke_query(request, &request->req_status);
 142                 if (MPI_STATUS_IGNORE != status) {
 143                     /* Do *NOT* set a new value for status->MPI_ERROR
 144                        here!  See MPI-1.1 doc, sec 3.2.5, p.22 */
 145                     int old_error = status->MPI_ERROR;
 146                     *status = request->req_status;
 147                     status->MPI_ERROR = old_error;
 148                 }
 149             } else if (MPI_STATUS_IGNORE != status) {
 150                 /* Do *NOT* set a new value for status->MPI_ERROR
 151                    here!  See MPI-1.1 doc, sec 3.2.5, p.22 */
 152                 int old_error = status->MPI_ERROR;
 153                 *status = request->req_status;
 154                 status->MPI_ERROR = old_error;
 155             }
 156 
 157             if( request->req_persistent ) {
 158                 request->req_state = OMPI_REQUEST_INACTIVE;
 159                 return OMPI_SUCCESS;
 160             }
 161             /* If there is an error on the request, don't free it */
 162             if (MPI_SUCCESS != request->req_status.MPI_ERROR) {
 163                 return request->req_status.MPI_ERROR;
 164             }
 165             /* If there's an error while freeing the request, assume
 166                that the request is still there.  Otherwise, Bad Things
 167                will happen later! */
 168             return ompi_request_free(rptr);
 169         }
 170     }
 171 
 172     /* Only fall through here if we found nothing */
 173     *index = MPI_UNDEFINED;
 174     if(num_requests_null_inactive != count) {
 175         *completed = false;
 176 #if OPAL_ENABLE_PROGRESS_THREADS == 0
 177         opal_progress();
 178 #endif
 179     } else {
 180         *completed = true;
 181         if (MPI_STATUS_IGNORE != status) {
 182             *status = ompi_status_empty;
 183         }
 184     }
 185     return OMPI_SUCCESS;
 186 }
 187 
 188 
 189 int ompi_request_default_test_all(
 190     size_t count,
 191     ompi_request_t ** requests,
 192     int *completed,
 193     ompi_status_public_t * statuses)
 194 {
 195     size_t i, rc;
 196     ompi_request_t **rptr;
 197     size_t num_completed = 0;
 198     ompi_request_t *request;
 199 
 200     opal_atomic_mb();
 201     rptr = requests;
 202     for (i = 0; i < count; i++, rptr++) {
 203         request = *rptr;
 204 
 205         if( request->req_state == OMPI_REQUEST_INACTIVE ||
 206             REQUEST_COMPLETE(request) ) {
 207             num_completed++;
 208         }
 209     }
 210 
 211     if (num_completed != count) {
 212         *completed = false;
 213 #if OPAL_ENABLE_PROGRESS_THREADS == 0
 214         opal_progress();
 215 #endif
 216         return OMPI_SUCCESS;
 217     }
 218 
 219     rptr = requests;
 220     *completed = true;
 221 
 222     rc = MPI_SUCCESS;
 223     if (MPI_STATUSES_IGNORE != statuses) {
 224         /* fill out completion status and free request if required */
 225         for( i = 0; i < count; i++, rptr++ ) {
 226             request  = *rptr;
 227             /* If the request is OMPI_REQUEST_INACTIVE set the status
 228              * to ompi_status_empty.
 229              */
 230             if( request->req_state == OMPI_REQUEST_INACTIVE ) {
 231                 statuses[i] = ompi_status_empty;
 232                 continue;
 233             }
 234             if (OMPI_REQUEST_GEN == request->req_type) {
 235                 ompi_grequest_invoke_query(request, &request->req_status);
 236             }
 237 #if OPAL_ENABLE_FT_CR == 1
 238             if( opal_cr_is_enabled) {
 239                 OMPI_CRCP_REQUEST_COMPLETE(request);
 240             }
 241 #endif
 242             statuses[i] = request->req_status;
 243             if( request->req_persistent ) {
 244                 request->req_state = OMPI_REQUEST_INACTIVE;
 245                 continue;
 246             }
 247             /* MPI-2:4.5.1 says that we can return MPI_ERR_IN_STATUS
 248                even if MPI_STATUSES_IGNORE was used.  Woot! */
 249             /* Only free the request if there was no error on it */
 250             if (MPI_SUCCESS == request->req_status.MPI_ERROR) {
 251                 int tmp = ompi_request_free(rptr);
 252                 if (tmp != OMPI_SUCCESS) {
 253                     return tmp;
 254                 }
 255             } else {
 256                 rc = MPI_ERR_IN_STATUS;
 257             }
 258         }
 259     } else {
 260         /* free request if required */
 261         for( i = 0; i < count; i++, rptr++ ) {
 262             request = *rptr;
 263             if( request->req_state == OMPI_REQUEST_INACTIVE) {
 264                 continue;
 265             }
 266             /* See note above: if a generalized request completes, we
 267                *have* to call the query fn, even if STATUSES_IGNORE
 268                was supplied */
 269             if (OMPI_REQUEST_GEN == request->req_type) {
 270                 ompi_grequest_invoke_query(request, &request->req_status);
 271             }
 272 #if OPAL_ENABLE_FT_CR == 1
 273             if( opal_cr_is_enabled) {
 274                 OMPI_CRCP_REQUEST_COMPLETE(request);
 275             }
 276 #endif
 277             if( request->req_persistent ) {
 278                 request->req_state = OMPI_REQUEST_INACTIVE;
 279                 continue;
 280             }
 281             /* Only free the request if there was no error */
 282             if (MPI_SUCCESS == request->req_status.MPI_ERROR) {
 283                 int tmp = ompi_request_free(rptr);
 284                 if (tmp != OMPI_SUCCESS) {
 285                     return tmp;
 286                 }
 287             } else {
 288                 rc = MPI_ERR_IN_STATUS;
 289             }
 290         }
 291     }
 292 
 293     return rc;
 294 }
 295 
 296 
 297 int ompi_request_default_test_some(
 298     size_t count,
 299     ompi_request_t ** requests,
 300     int * outcount,
 301     int * indices,
 302     ompi_status_public_t * statuses)
 303 {
 304     size_t i, num_requests_null_inactive = 0, num_requests_done = 0;
 305     int rc = OMPI_SUCCESS;
 306     ompi_request_t **rptr;
 307     ompi_request_t *request;
 308 
 309     opal_atomic_mb();
 310     rptr = requests;
 311     for (i = 0; i < count; i++, rptr++) {
 312         request = *rptr;
 313         if (request->req_state == OMPI_REQUEST_INACTIVE) {
 314             num_requests_null_inactive++;
 315             continue;
 316         }
 317         if( REQUEST_COMPLETE(request) ) {
 318 #if OPAL_ENABLE_FT_CR == 1
 319             if( opal_cr_is_enabled) {
 320                 OMPI_CRCP_REQUEST_COMPLETE(request);
 321             }
 322 #endif
 323             indices[num_requests_done++] = i;
 324         }
 325     }
 326 
 327     /*
 328      * If there are no active requests, no need to progress
 329      */
 330     if (num_requests_null_inactive == count) {
 331         *outcount = MPI_UNDEFINED;
 332         return OMPI_SUCCESS;
 333     }
 334 
 335     *outcount = num_requests_done;
 336 
 337     if (num_requests_done == 0) {
 338 #if OPAL_ENABLE_PROGRESS_THREADS == 0
 339         opal_progress();
 340 #endif
 341         return OMPI_SUCCESS;
 342     }
 343 
 344     /* fill out completion status and free request if required */
 345     for( i = 0; i < num_requests_done; i++) {
 346         request = requests[indices[i]];
 347 
 348         /* See note above: if a generalized request completes, we
 349            *have* to call the query fn, even if STATUSES_IGNORE
 350            was supplied */
 351         if (OMPI_REQUEST_GEN == request->req_type) {
 352             ompi_grequest_invoke_query(request, &request->req_status);
 353         }
 354         if (MPI_STATUSES_IGNORE != statuses) {
 355             statuses[i] = request->req_status;
 356         }
 357 
 358         if (MPI_SUCCESS != request->req_status.MPI_ERROR) {
 359             rc = MPI_ERR_IN_STATUS;
 360         }
 361 
 362         if( request->req_persistent ) {
 363             request->req_state = OMPI_REQUEST_INACTIVE;
 364         } else {
 365             /* Only free the request if there was no error */
 366             if (MPI_SUCCESS == request->req_status.MPI_ERROR) {
 367                 int tmp;
 368                 tmp = ompi_request_free(&(requests[indices[i]]));
 369                 if (OMPI_SUCCESS != tmp) {
 370                     return tmp;
 371                 }
 372             }
 373         }
 374     }
 375 
 376     return rc;
 377 }

/* [<][>][^][v][top][bottom][index][help] */