1
1
openmpi/src/errhandler/errhandler.h

266 строки
7.7 KiB
C
Исходник Обычный вид История

/*
* $HEADER$
*/
/** @file **/
#ifndef LAM_ERRHANDLER_H
#define LAM_ERRHANDLER_H
#include "lam_config.h"
#include "mpi.h"
#include "lfc/lam_object.h"
#include "lfc/lam_pointer_array.h"
/*
* These must correspond to the fortran handle indices
*/
#define LAM_ERRHANDLER_NULL_FORTRAN 0
#define LAM_ERRORS_ARE_FATAL_FORTRAN 1
#define LAM_ERRORS_RETURN_FORTRAN 2
/**
* Typedef for all fortran errhandler functions
*/
typedef void (lam_errhandler_fortran_handler_fn_t)(int *, int *, ...);
/**
* Enum used to describe what kind MPI object an error handler is used for
*/
enum lam_errhandler_type_t {
LAM_ERRHANDLER_TYPE_COMM,
LAM_ERRHANDLER_TYPE_WIN,
LAM_ERRHANDLER_TYPE_FILE
};
typedef enum lam_errhandler_type_t lam_errhandler_type_t;
/**
* Back-end type for MPI_Errorhandler.
*/
struct lam_errhandler_t {
lam_object_t super;
char eh_name[MPI_MAX_OBJECT_NAME];
/* Type of MPI object that this handler is for */
lam_errhandler_type_t eh_mpi_object_type;
/* Flags about the error handler */
bool eh_is_intrinsic;
bool eh_fortran_function;
/* Function pointers */
union {
MPI_Comm_errhandler_fn *c_comm_fn;
MPI_File_errhandler_fn *c_file_fn;
MPI_Win_errhandler_fn *c_win_fn;
lam_errhandler_fortran_handler_fn_t *fort_fn;
} eh_func;
/* index in Fortran <-> C translation array */
int eh_f_to_c_index;
};
typedef struct lam_errhandler_t lam_errhandler_t;
/**
* Global variable for MPI_ERRHANDLER_NULL
*/
extern lam_errhandler_t lam_mpi_errhandler_null;
/**
* Global variable for MPI_ERRORS_ARE_FATAL
*/
extern lam_errhandler_t lam_mpi_errors_are_fatal;
/**
* Global variable for MPI_ERRORS_RETURN
*/
extern lam_errhandler_t lam_mpi_errors_return;
/**
* Table for Fortran <-> C errhandler handle conversion
*/
extern lam_pointer_array_t *lam_errhandler_f_to_c_table;
/**
* This is the macro to invoke to directly invoke an MPI error
* handler.
*
* @param mpi_object The MPI object to invoke the errhandler on (a
* comm, win, or win)
* @param err_code The error code
* @param message Any additional message; typically the name of the
* MPI function that is invoking the error.
*
* This macro is used when you want to directly invoke the error
* handler. It is exactly equivalent to calling
* lam_errhandler_invoke() directly, but is provided to have a
* parallel invocation to LAM_ERRHANDLER_CHECK() and LAM_ERRHANDLER_RETURN().
*/
#define LAM_ERRHANDLER_INVOKE(mpi_object, err_code, message) \
lam_errhandler_invoke((mpi_object) != NULL ? (mpi_object)->error_handler : NULL, (mpi_object), \
(err_code), (message));
/**
* Conditionally invoke an MPI error handler.
*
* @param rc The return code to check
* @param errhandler The MPI_Errhandler to invoke
* @param mpi_object The MPI object to invoke the errhandler on (a
* comm, win, or win)
* @param err_code The error code
* @param message Any additional message; typically the name of the
* MPI function that is invoking the error.
*
* This macro will invoke the error handler if the return code is not
* LAM_SUCCESS.
*/
#define LAM_ERRHANDLER_CHECK(rc, mpi_object, err_code, message) \
if (rc != LAM_SUCCESS) { \
lam_errhandler_invoke((mpi_object) != NULL ? (mpi_object)->error_handler : NULL, (mpi_object), \
(err_code), (message)); \
return (err_code); \
}
/**
* Conditionally invoke an MPI error handler; if there is no error,
* return MPI_SUCCESS.
*
* @param rc The return code to check
* @param errhandler The MPI_Errhandler to invoke
* @param mpi_object The MPI object to invoke the errhandler on (a
* comm, win, or win)
* @param err_code The error code
* @param message Any additional message; typically the name of the
* MPI function that is invoking the error.
*
* This macro will invoke the error handler if the return code is not
* LAM_SUCCESS. If the return code is LAM_SUCCESS, then return
* MPI_SUCCESS.
*/
#define LAM_ERRHANDLER_RETURN(rc, mpi_object, err_code, message) \
if (rc != LAM_SUCCESS) { \
lam_errhandler_invoke((mpi_object != NULL) ? (mpi_object)->error_handler : NULL, (mpi_object), \
(err_code), (message)); \
return (err_code); \
} else { \
return MPI_SUCCESS; \
}
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
/**
* Initialize the error handler interface.
*
* @returns LAM_SUCCESS Upon success
* @returns LAM_ERROR Otherwise
*
* Invoked from lam_mpi_init(); sets up the error handler interface,
* creates the predefined MPI errorhandlers, and creates the
* corresopnding F2C translation table.
*/
int lam_errhandler_init(void);
/**
* Finalize the error handler interface.
*
* @returns LAM_SUCCESS Always
*
* Invokes from lam_mpi_finalize(); tears down the error handler
* interface, and destroys the F2C translation table.
*/
int lam_errhandler_finalize(void);
/**
* \internal
*
* This function should not be invoked directly; it should only be
* invoked by LAM_ERRHANDLER_INVOKE(), LAM_ERRHANDLER_CHECK(), or
* LAM_ERRHANDLER_RETURN().
*
* @param errhandler The MPI_Errhandler to invoke
* @param mpi_object The MPI object to invoke the errhandler on (a
* comm, win, or win)
* @param err_code The error code
* @param message Any additional message; typically the name of the
* MPI function that is invoking the error.
*
* @returns err_code The same value as the parameter
*
* This function invokes the MPI exception function on the error
* handler. If the errhandler was created from fortran, the error
* handler will be invoked with fortran linkage. Otherwise, it is
* invoked with C linkage.
*
* If this function returns, it returns the err_code. Note that it
* may not return (e.g., for MPI_ERRORS_ARE_FATAL).
*/
int lam_errhandler_invoke(lam_errhandler_t *errhandler, void *mpi_object,
int err_code, char *message);
/**
* Create a lam_errhandler_t
*
* @param object_type Enum of the type of MPI object
* @param func Function pointer of the error handler
*
* @returns errhandler Pointer to the lam_errorhandler_t that will be
* created and returned
*
* This function is called as the back-end of all the
* MPI_*_CREATE_ERRHANDLER functions. It creates a new
* lam_errhandler_t object, initializes it to the correct object
* type, and sets the callback function on it.
*
* The type of the function pointer is (arbitrarily) the fortran
* function handler type. Since this function has to accept 4
* different function pointer types (lest we have 4 different
* functions to create errhandlers), the fortran one was picked
* arbitrarily. Note that (void*) is not sufficient because at
* least theoretically, a sizeof(void*) may not necessarily be the
* same as sizeof(void(*)).
*
* NOTE: It *always* sets the "fortran" flag to false. Fortran
* wrappers for MPI_*_CREATE_ERRHANDLER are expected to reset this
* flag to false manually.
*/
lam_errhandler_t *lam_errhandler_create(lam_errhandler_type_t object_type,
lam_errhandler_fortran_handler_fn_t *func);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif
/**
* Check to see if an errhandler is intrinsic.
*
* @param errhandler The errhandler to check
*
* @returns true If the errhandler is intrinsic
* @returns false If the errhandler is not intrinsic
*
* Self-explanitory. This is needed in a few top-level MPI functions;
* this function is provided to hide the internal structure field
* names.
*/
static inline bool lam_errhandler_is_intrinsic(lam_errhandler_t *errhandler)
{
return errhandler->eh_is_intrinsic;
}
#endif /* LAM_ERRHANDLER_H */