1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
|
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2006 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/**
* @file
*
* Top-level description of requests
*/
#ifndef OMPI_REQUEST_H
#define OMPI_REQUEST_H
#include "mpi.h"
#include "ompi/class/ompi_free_list.h"
#include "ompi/class/ompi_pointer_array.h"
#include "opal/threads/condition.h"
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
/**
* Request class
*/
OMPI_DECLSPEC OBJ_CLASS_DECLARATION(ompi_request_t);
/**
* Enum inidicating the type of the request
*/
typedef enum {
OMPI_REQUEST_PML, /**< MPI point-to-point request */
OMPI_REQUEST_IO, /**< MPI-2 IO request */
OMPI_REQUEST_GEN, /**< MPI-2 generalized request */
OMPI_REQUEST_WIN, /**< MPI-2 one-sided request */
OMPI_REQUEST_NULL, /**< NULL request */
OMPI_REQUEST_NOOP, /**< A request that does nothing (e.g., to PROC_NULL) */
OMPI_REQUEST_MAX /**< Maximum request type */
} ompi_request_type_t;
/**
* Enum indicating the state of the request
*/
typedef enum {
/** Indicates that the request should not be progressed */
OMPI_REQUEST_INVALID,
/** A defined, but inactive request (i.e., it's valid, but should
not be progressed) */
OMPI_REQUEST_INACTIVE,
/** A valid and progressing request */
OMPI_REQUEST_ACTIVE,
/** The request has been cancelled */
OMPI_REQUEST_CANCELLED
} ompi_request_state_t;
struct ompi_request_t;
/*
* Required function to free the request and any associated resources.
*/
typedef int (*ompi_request_free_fn_t)(struct ompi_request_t** rptr);
/*
* Optional function to cancel a pending request.
*/
typedef int (*ompi_request_cancel_fn_t)(struct ompi_request_t* request, int flag);
/**
* Forward declaration
*/
struct ompi_communicator_t;
/**
* Forward declaration
*/
struct ompi_win_t;
/**
* Forward declaration
*/
struct ompi_file_t;
/**
* Union for holding several different MPI pointer types on the request
*/
typedef union ompi_mpi_object_t {
struct ompi_communicator_t *comm;
struct ompi_file_t *file;
struct ompi_win_t *win;
} ompi_mpi_object_t;
/**
* Main top-level request struct definition
*/
struct ompi_request_t {
ompi_free_list_item_t super; /**< Base type */
ompi_request_type_t req_type; /**< Enum indicating the type of the request */
ompi_status_public_t req_status; /**< Completion status */
volatile bool req_complete; /**< Flag indicating wether request has completed */
volatile ompi_request_state_t req_state; /**< enum indicate state of the request */
bool req_persistent; /**< flag indicating if the this is a persistent request */
int req_f_to_c_index; /**< Index in Fortran <-> C translation array */
ompi_request_free_fn_t req_free; /**< Called by free */
ompi_request_cancel_fn_t req_cancel; /**< Optional function to cancel the request */
ompi_mpi_object_t req_mpi_object; /**< Pointer to MPI object that created this request */
};
/**
* Convenience typedef
*/
typedef struct ompi_request_t ompi_request_t;
/**
* Initialize a request. This is a macro to avoid function call
* overhead, since this is typically invoked in the critical
* performance path (since requests may be re-used, it is possible
* that we will have to initialize a request multiple times).
*/
#define OMPI_REQUEST_INIT(request, persistent) \
do { \
(request)->req_state = OMPI_REQUEST_INACTIVE; \
(request)->req_complete = false; \
(request)->req_persistent = (persistent); \
} while (0);
/**
* Finalize a request. This is a macro to avoid function call
* overhead, since this is typically invoked in the critical
* performance path (since requests may be re-used, it is possible
* that we will have to finalize a request multiple times).
*
* When finalizing a request, if MPI_Request_f2c() was previously
* invoked on that request, then this request was added to the f2c
* table, and we need to remove it
*
* This function should be called only from the MPI layer. It should
* never be called from the PML. It take care of the upper level clean-up.
* When the user call MPI_Request_free we should release all MPI level
* ressources, so we have to call this function too.
*/
#define OMPI_REQUEST_FINI(request) \
do { \
(request)->req_state = OMPI_REQUEST_INVALID; \
if (MPI_UNDEFINED != (request)->req_f_to_c_index) { \
ompi_pointer_array_set_item(&ompi_request_f_to_c_table, \
(request)->req_f_to_c_index, NULL); \
(request)->req_f_to_c_index = MPI_UNDEFINED; \
} \
} while (0);
/**
* Globals used for tracking requests and request completion.
*/
OMPI_DECLSPEC extern ompi_pointer_array_t ompi_request_f_to_c_table;
OMPI_DECLSPEC extern size_t ompi_request_waiting;
OMPI_DECLSPEC extern size_t ompi_request_completed;
OMPI_DECLSPEC extern int32_t ompi_request_poll;
OMPI_DECLSPEC extern opal_mutex_t ompi_request_lock;
OMPI_DECLSPEC extern opal_condition_t ompi_request_cond;
OMPI_DECLSPEC extern ompi_request_t ompi_request_null;
OMPI_DECLSPEC extern ompi_request_t ompi_request_empty;
OMPI_DECLSPEC extern ompi_status_public_t ompi_status_empty;
/**
* Initialize the MPI_Request subsystem; invoked during MPI_INIT.
*/
OMPI_DECLSPEC int ompi_request_init(void);
/**
* Free a persistent request to a MPI_PROC_NULL peer (there's no
* freelist to put it back to, so we have to actually OBJ_RELEASE it).
*/
OMPI_DECLSPEC int ompi_request_persistent_proc_null_free(ompi_request_t **request);
/**
* Shut down the MPI_Request subsystem; invoked during MPI_FINALIZE.
*/
OMPI_DECLSPEC int ompi_request_finalize(void);
/**
* Cancel a pending request.
*/
static inline int ompi_request_cancel(ompi_request_t* request)
{
if (request->req_cancel != NULL) {
return request->req_cancel(request, true);
}
return OMPI_SUCCESS;
}
/**
* Signal a request as complete. Note this will
* wake any thread pending on the request.
*/
OMPI_DECLSPEC int ompi_request_complete(ompi_request_t* request);
/**
* Free a request.
*
* @param request (INOUT) Pointer to request.
*/
static inline int ompi_request_free(ompi_request_t** request)
{
return (*request)->req_free(request);
}
/**
* Non-blocking test for request completion.
*
* @param request (IN) Array of requests
* @param complete (OUT) Flag indicating if index is valid (a request completed).
* @param status (OUT) Status of completed request.
* @return OMPI_SUCCESS or failure status.
*
* Note that upon completion, the request is freed, and the
* request handle at index set to NULL.
*/
OMPI_DECLSPEC int ompi_request_test( ompi_request_t ** rptr,
int *completed,
ompi_status_public_t * status );
/**
* Non-blocking test for request completion.
*
* @param count (IN) Number of requests
* @param request (IN) Array of requests
* @param index (OUT) Index of first completed request.
* @param complete (OUT) Flag indicating if index is valid (a request completed).
* @param status (OUT) Status of completed request.
* @return OMPI_SUCCESS or failure status.
*
* Note that upon completion, the request is freed, and the
* request handle at index set to NULL.
*/
OMPI_DECLSPEC int ompi_request_test_any(
size_t count,
ompi_request_t ** requests,
int *index,
int *completed,
ompi_status_public_t * status);
/**
* Non-blocking test for request completion.
*
* @param count (IN) Number of requests
* @param requests (IN) Array of requests
* @param completed (OUT) Flag indicating wether all requests completed.
* @param statuses (OUT) Array of completion statuses.
* @return OMPI_SUCCESS or failure status.
*
* This routine returns completed==true if all requests have completed.
* The statuses parameter is only updated if all requests completed. Likewise,
* the requests array is not modified (no requests freed), unless all requests
* have completed.
*/
OMPI_DECLSPEC int ompi_request_test_all(
size_t count,
ompi_request_t ** requests,
int *completed,
ompi_status_public_t * statuses);
/**
* Non-blocking test for some of N requests to complete.
*
* @param count (IN) Number of requests
* @param requests (INOUT) Array of requests
* @param outcount (OUT) Number of finished requests
* @param indices (OUT) Indices of the finished requests
* @param statuses (OUT) Array of completion statuses.
* @return OMPI_SUCCESS, OMPI_ERR_IN_STATUS or failure status.
*
*/
OMPI_DECLSPEC int ompi_request_test_some(
size_t count,
ompi_request_t ** requests,
int * outcount,
int * indices,
ompi_status_public_t * statuses);
/**
* Wait (blocking-mode) for one requests to complete.
*
* @param request (IN) Pointer to request.
* @param status (OUT) Status of completed request.
* @return OMPI_SUCCESS or failure status.
*
*/
int ompi_request_wait(
ompi_request_t ** req_ptr,
ompi_status_public_t * status);
/**
* Wait (blocking-mode) for one of N requests to complete.
*
* @param count (IN) Number of requests
* @param requests (IN) Array of requests
* @param index (OUT) Index into request array of completed request.
* @param status (OUT) Status of completed request.
* @return OMPI_SUCCESS or failure status.
*
*/
OMPI_DECLSPEC int ompi_request_wait_any(
size_t count,
ompi_request_t ** requests,
int *index,
ompi_status_public_t * status);
/**
* Wait (blocking-mode) for all of N requests to complete.
*
* @param count (IN) Number of requests
* @param requests (IN) Array of requests
* @param statuses (OUT) Array of completion statuses.
* @return OMPI_SUCCESS or failure status.
*
*/
OMPI_DECLSPEC int ompi_request_wait_all(
size_t count,
ompi_request_t ** requests,
ompi_status_public_t * statuses);
/**
* Wait (blocking-mode) for some of N requests to complete.
*
* @param count (IN) Number of requests
* @param requests (INOUT) Array of requests
* @param outcount (OUT) Number of finished requests
* @param indices (OUT) Indices of the finished requests
* @param statuses (OUT) Array of completion statuses.
* @return OMPI_SUCCESS, OMPI_ERR_IN_STATUS or failure status.
*
*/
OMPI_DECLSPEC int ompi_request_wait_some(
size_t count,
ompi_request_t ** requests,
int * outcount,
int * indices,
ompi_status_public_t * statuses);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif
#endif
|