OpenMPI  0.1.1
errhandler.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4  * University Research and Technology
5  * Corporation. All rights reserved.
6  * Copyright (c) 2004-2011 The University of Tennessee and The University
7  * of Tennessee Research Foundation. All rights
8  * reserved.
9  * Copyright (c) 2004-2005 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) 2008-2010 Cisco Systems, Inc. All rights reserved.
14  * Copyright (c) 2008-2009 Sun Microsystems, Inc. All rights reserved.
15  * Copyright (c) 2010-2012 Oak Ridge National Labs. All rights reserved.
16  *
17  * $COPYRIGHT$
18  *
19  * Additional copyrights may follow
20  *
21  * $HEADER$
22  */
23 /** @file **/
24 
25 #ifndef OMPI_ERRHANDLER_H
26 #define OMPI_ERRHANDLER_H
27 
28 #include "ompi_config.h"
29 
30 #include "mpi.h"
31 
32 #include "opal/prefetch.h"
33 #include "opal/class/opal_object.h"
35 
37 #include "ompi/errhandler/errhandler_predefined.h"
39 
40 #if OPAL_ENABLE_FT_MPI
41 #include "orte/mca/plm/plm_types.h"
42 #include "ompi/proc/proc.h"
43 #endif
44 
45 #include "orte/types.h"
46 
47 BEGIN_C_DECLS
48 
49 /*
50  * These must correspond to the fortran handle indices
51  */
52 enum {
53  OMPI_ERRHANDLER_NULL_FORTRAN = 0,
54  OMPI_ERRORS_ARE_FATAL_FORTRAN,
55  OMPI_ERRORS_RETURN_FORTRAN
56 };
57 
58 
59 /**
60  * Typedef for all fortran errhandler functions
61  */
62 typedef void (ompi_errhandler_fortran_handler_fn_t)(MPI_Fint *,
63  MPI_Fint *, ...);
64 
65 /**
66  * Typedef for generic errhandler function
67  */
68 typedef void (ompi_errhandler_generic_handler_fn_t)(void *, int *, ...);
69 
70 /**
71  * Enum to denote what language the error handler was created from
72  */
74  OMPI_ERRHANDLER_LANG_C,
75  OMPI_ERRHANDLER_LANG_CXX,
76  OMPI_ERRHANDLER_LANG_FORTRAN
77 };
79 
80 
81 /**
82  * Enum used to describe what kind MPI object an error handler is used for
83  */
85  OMPI_ERRHANDLER_TYPE_PREDEFINED,
86  OMPI_ERRHANDLER_TYPE_COMM,
87  OMPI_ERRHANDLER_TYPE_WIN,
88  OMPI_ERRHANDLER_TYPE_FILE
89 };
91 
92 
93 /*
94  * Need to forward declare this for use in ompi_errhandle_cxx_dispatch_fn_t.
95  */
96 struct ompi_errhandler_t;
97 
98 /**
99  * C++ invocation function signature
100  */
101 typedef void (ompi_errhandler_cxx_dispatch_fn_t)(struct ompi_errhandler_t *errhandler,
102  void *handle, int *err_code,
103  const char *message);
104 
105 /**
106  * Back-end type for MPI_Errorhandler.
107  */
109  opal_object_t super;
110 
111  char eh_name[MPI_MAX_OBJECT_NAME];
112  /* Type of MPI object that this handler is for */
113 
114  ompi_errhandler_type_t eh_mpi_object_type;
115 
116  /* What language was the error handler created in */
117  ompi_errhandler_lang_t eh_lang;
118 
119  /* Function pointers. Note that we *have* to have all 4 types
120  (vs., for example, a union) because the predefined errhandlers
121  can be invoked on any MPI object type, so we need callbacks for
122  all of three. */
123  MPI_Comm_errhandler_function *eh_comm_fn;
124  ompi_file_errhandler_fn *eh_file_fn;
125  MPI_Win_errhandler_function *eh_win_fn;
127 
128  /* Have separate callback for C++ errhandlers. This pointer is
129  initialized to NULL and will be set explicitly by the C++
130  bindings for Create_errhandler. This function is invoked
131  when eh_lang==OMPI_ERRHANDLER_LANG_CXX so that the user's
132  callback function can be invoked with the right language
133  semantics. */
134  ompi_errhandler_cxx_dispatch_fn_t *eh_cxx_dispatch_fn;
135 
136  /* index in Fortran <-> C translation array */
137  int eh_f_to_c_index;
138 };
139 typedef struct ompi_errhandler_t ompi_errhandler_t;
140 
141 /**
142  * Padded struct to maintain back compatibiltiy.
143  * See ompi/communicator/communicator.h comments with struct ompi_communicator_t
144  * for full explanation why we chose the following padding construct for predefines.
145  */
146 #define PREDEFINED_ERRHANDLER_PAD 1024
147 
149  struct ompi_errhandler_t eh;
150  char padding[PREDEFINED_ERRHANDLER_PAD - sizeof(ompi_errhandler_t)];
151 };
152 
154 
155 
156 /**
157  * Global variable for MPI_ERRHANDLER_NULL
158  */
160 
161 /**
162  * Global variable for MPI_ERRORS_ARE_FATAL
163  */
165 
166 /**
167  * Global variable for MPI_ERRORS_RETURN
168  */
170 
171 /**
172  * Global variable for MPI::ERRORS_THROW_EXCEPTIONS. Will abort if
173  * MPI_INIT wasn't called as MPI::INIT
174  */
176 
177 /**
178  * Table for Fortran <-> C errhandler handle conversion
179  */
181 
182 
183 /**
184  * Forward declaration so that we don't have to include
185  * request/request.h here.
186  */
187 struct ompi_request_t;
188 
189 
190 /**
191  * This is the macro to check the state of MPI and determine whether
192  * it was properly initialized and not yet finalized.
193  *
194  * This macro directly invokes the ompi_mpi_errors_are_fatal_handler()
195  * when an error occurs because MPI_COMM_WORLD does not exist (because
196  * we're before MPI_Init() or after MPI_Finalize()).
197  */
198 #define OMPI_ERR_INIT_FINALIZE(name) \
199  if( OPAL_UNLIKELY(!ompi_mpi_initialized || ompi_mpi_finalized) ) { \
200  ompi_mpi_errors_are_fatal_comm_handler(NULL, NULL, name); \
201  }
202 
203 /**
204  * This is the macro to invoke to directly invoke an MPI error
205  * handler.
206  *
207  * @param mpi_object The MPI object to invoke the errhandler on (a
208  * comm, win, or win)
209  * @param err_code The error code
210  * @param message Any additional message; typically the name of the
211  * MPI function that is invoking the error.
212  *
213  * This macro is used when you want to directly invoke the error
214  * handler. It is exactly equivalent to calling
215  * ompi_errhandler_invoke() directly, but is provided to have a
216  * parallel invocation to OMPI_ERRHANDLER_CHECK() and OMPI_ERRHANDLER_RETURN().
217  */
218 #define OMPI_ERRHANDLER_INVOKE(mpi_object, err_code, message) \
219  ompi_errhandler_invoke((mpi_object)->error_handler, \
220  (mpi_object), \
221  (int)(mpi_object)->errhandler_type, \
222  ompi_errcode_get_mpi_code(err_code), \
223  (message));
224 
225 /**
226  * Conditionally invoke an MPI error handler.
227  *
228  * @param rc The return code to check
229  * @param mpi_object The MPI object to invoke the errhandler on (a
230  * comm, win, or win)
231  * @param err_code The error code
232  * @param message Any additional message; typically the name of the
233  * MPI function that is invoking the error.
234  *
235  * This macro will invoke the error handler if the return code is not
236  * OMPI_SUCCESS.
237  */
238 #define OMPI_ERRHANDLER_CHECK(rc, mpi_object, err_code, message) \
239  if( OPAL_UNLIKELY(rc != OMPI_SUCCESS) ) { \
240  int __mpi_err_code = ompi_errcode_get_mpi_code(err_code); \
241  OPAL_CR_EXIT_LIBRARY() \
242  ompi_errhandler_invoke((mpi_object)->error_handler, \
243  (mpi_object), \
244  (int) (mpi_object)->errhandler_type, \
245  (__mpi_err_code), \
246  (message)); \
247  return (__mpi_err_code); \
248  }
249 
250 /**
251  * Conditionally invoke an MPI error handler; if there is no error,
252  * return MPI_SUCCESS.
253  *
254  * @param rc The return code to check
255  * @param mpi_object The MPI object to invoke the errhandler on (a
256  * comm, win, or win)
257  * @param err_code The error code
258  * @param message Any additional message; typically the name of the
259  * MPI function that is invoking the error.
260  *
261  * This macro will invoke the error handler if the return code is not
262  * OMPI_SUCCESS. If the return code is OMPI_SUCCESS, then return
263  * MPI_SUCCESS.
264  */
265 #define OMPI_ERRHANDLER_RETURN(rc, mpi_object, err_code, message) \
266  OPAL_CR_EXIT_LIBRARY() \
267  if ( OPAL_UNLIKELY(OMPI_SUCCESS != rc) ) { \
268  int __mpi_err_code = ompi_errcode_get_mpi_code(err_code); \
269  ompi_errhandler_invoke((mpi_object)->error_handler, \
270  (mpi_object), \
271  (int)(mpi_object)->errhandler_type, \
272  (__mpi_err_code), \
273  (message)); \
274  return (__mpi_err_code); \
275  } else { \
276  return MPI_SUCCESS; \
277  }
278 
279 
280 
281  /**
282  * Initialize the error handler interface.
283  *
284  * @returns OMPI_SUCCESS Upon success
285  * @returns OMPI_ERROR Otherwise
286  *
287  * Invoked from ompi_mpi_init(); sets up the error handler interface,
288  * creates the predefined MPI errorhandlers, and creates the
289  * corresopnding F2C translation table.
290  */
291  int ompi_errhandler_init(void);
292 
293  /**
294  * Finalize the error handler interface.
295  *
296  * @returns OMPI_SUCCESS Always
297  *
298  * Invokes from ompi_mpi_finalize(); tears down the error handler
299  * interface, and destroys the F2C translation table.
300  */
301  int ompi_errhandler_finalize(void);
302 
303  /**
304  * \internal
305  *
306  * This function should not be invoked directly; it should only be
307  * invoked by OMPI_ERRHANDLER_INVOKE(), OMPI_ERRHANDLER_CHECK(), or
308  * OMPI_ERRHANDLER_RETURN().
309  *
310  * @param errhandler The MPI_Errhandler to invoke
311  * @param mpi_object The MPI object to invoke the errhandler on (a
312  * comm, win, or win)
313  * @param type The type of the MPI object. Necessary, since
314  * you can not assign a single type to the predefined
315  * error handlers. This information is therefore
316  * stored on the MPI object itself.
317  * @param err_code The error code
318  * @param message Any additional message; typically the name of the
319  * MPI function that is invoking the error.
320  *
321  * @returns err_code The same value as the parameter
322  *
323  * This function invokes the MPI exception function on the error
324  * handler. If the errhandler was created from fortran, the error
325  * handler will be invoked with fortran linkage. Otherwise, it is
326  * invoked with C linkage.
327  *
328  * If this function returns, it returns the err_code. Note that it
329  * may not return (e.g., for MPI_ERRORS_ARE_FATAL).
330  */
331  OMPI_DECLSPEC int ompi_errhandler_invoke(ompi_errhandler_t *errhandler, void *mpi_object,
332  int type, int err_code, const char *message);
333 
334 
335  /**
336  * Invoke an MPI exception on the first request found in the array
337  * that has a non-MPI_SUCCESS value for MPI_ERROR in its status. It
338  * is safe to invoke this function if none of the requests have an
339  * outstanding error; MPI_SUCCESS will be returned.
340  */
341  int ompi_errhandler_request_invoke(int count,
342  struct ompi_request_t **requests,
343  const char *message);
344 
345  /**
346  * Create a ompi_errhandler_t
347  *
348  * @param object_type Enum of the type of MPI object
349  * @param func Function pointer of the error handler
350  *
351  * @returns errhandler Pointer to the ompi_errorhandler_t that will be
352  * created and returned
353  *
354  * This function is called as the back-end of all the
355  * MPI_*_CREATE_ERRHANDLER functions. It creates a new
356  * ompi_errhandler_t object, initializes it to the correct object
357  * type, and sets the callback function on it.
358  *
359  * The type of the function pointer is (arbitrarily) the fortran
360  * function handler type. Since this function has to accept 4
361  * different function pointer types (lest we have 4 different
362  * functions to create errhandlers), the fortran one was picked
363  * arbitrarily. Note that (void*) is not sufficient because at
364  * least theoretically, a sizeof(void*) may not necessarily be the
365  * same as sizeof(void(*)).
366  */
369  ompi_errhandler_lang_t language);
370 
371 /**
372  * Callback function from runtime layer to alert the MPI layer of an error at
373  * the runtime layer.
374  *
375  * @param procs The names of the processes that have failed.
376  *
377  * This function is used to alert the MPI layer to a specific fault at the
378  * runtime layer. Currently, the only faults reported using this method are
379  * process failures. The MPI layer has the option to perform whatever actions it
380  * needs to stabalize itself and continue running, abort, etc.
381  */
382 OMPI_DECLSPEC void ompi_errhandler_runtime_callback(opal_pointer_array_t *procs);
383 
384 /**
385  * Check to see if an errhandler is intrinsic.
386  *
387  * @param errhandler The errhandler to check
388  *
389  * @returns true If the errhandler is intrinsic
390  * @returns false If the errhandler is not intrinsic
391  *
392  * Self-explanitory. This is needed in a few top-level MPI functions;
393  * this function is provided to hide the internal structure field
394  * names.
395  */
396 static inline bool ompi_errhandler_is_intrinsic(ompi_errhandler_t *errhandler)
397 {
398  if ( OMPI_ERRHANDLER_TYPE_PREDEFINED == errhandler->eh_mpi_object_type )
399  return true;
400 
401  return false;
402 }
403 
404 #if OPAL_ENABLE_FT_MPI
405 /**
406  * Initialize/Finalize the connection with the Runtime Error Management
407  * mechanism to be notified of process failures.
408  */
409 int ompi_errhandler_internal_rte_init(void);
410 int ompi_errhandler_internal_rte_finalize(void);
411 OMPI_DECLSPEC int ompi_errmgr_mark_failed_peer(ompi_proc_t *ompi_proc, orte_proc_state_t state);
412 
413 #endif /* OPAL_ENABLE_FT_MPI */
414 
415 END_C_DECLS
416 
417 #endif /* OMPI_ERRHANDLER_H */
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errhandler_null
Global variable for MPI_ERRHANDLER_NULL.
Definition: errhandler.c:57
dynamic pointer array
Definition: opal_pointer_array.h:45
Definition: errhandler.h:148
Back-end type for MPI_Errorhandler.
Definition: errhandler.h:108
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errors_are_fatal
Global variable for MPI_ERRORS_ARE_FATAL.
Definition: errhandler.c:58
See opal_bitmap.h for an explanation of why there is a split between OPAL and ORTE for this generic c...
Process identification structure interface.
Remote Open MPI process structure.
Definition: proc.h:56
static bool ompi_errhandler_is_intrinsic(ompi_errhandler_t *errhandler)
Check to see if an errhandler is intrinsic.
Definition: errhandler.h:396
void( ompi_errhandler_generic_handler_fn_t)(void *, int *,...)
Typedef for generic errhandler function.
Definition: errhandler.h:68
OMPI_DECLSPEC void ompi_errhandler_runtime_callback(opal_pointer_array_t *procs)
Callback function from runtime layer to alert the MPI layer of an error at the runtime layer...
Definition: errhandler.c:256
Interface into the MPI portion of the Open MPI Run Time Environment.
ompi_errhandler_lang_t
Enum to denote what language the error handler was created from.
Definition: errhandler.h:73
void( ompi_errhandler_cxx_dispatch_fn_t)(struct ompi_errhandler_t *errhandler, void *handle, int *err_code, const char *message)
C++ invocation function signature.
Definition: errhandler.h:101
int ompi_errhandler_request_invoke(int count, struct ompi_request_t **requests, const char *message)
Invoke an MPI exception on the first request found in the array that has a non-MPI_SUCCESS value for ...
Definition: errhandler_invoke.c:115
Base object.
Definition: opal_object.h:182
OMPI_DECLSPEC ompi_errhandler_t * ompi_errhandler_create(ompi_errhandler_type_t object_type, ompi_errhandler_generic_handler_fn_t *func, ompi_errhandler_lang_t language)
Create a ompi_errhandler_t.
Definition: errhandler.c:208
void( ompi_errhandler_fortran_handler_fn_t)(MPI_Fint *, MPI_Fint *,...)
Typedef for all fortran errhandler functions.
Definition: errhandler.h:62
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errors_throw_exceptions
Global variable for MPI::ERRORS_THROW_EXCEPTIONS.
Definition: errhandler.c:60
OMPI_DECLSPEC opal_pointer_array_t ompi_errhandler_f_to_c_table
Table for Fortran <-> C errhandler handle conversion.
Definition: errhandler.c:40
#define PREDEFINED_ERRHANDLER_PAD
Padded struct to maintain back compatibiltiy.
Definition: errhandler.h:146
Compiler-specific prefetch functions.
int ompi_errhandler_finalize(void)
Finalize the error handler interface.
Definition: errhandler.c:158
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errors_return
Global variable for MPI_ERRORS_RETURN.
Definition: errhandler.c:59
A simple C-language object-oriented system with single inheritance and ownership-based memory managem...
int ompi_errhandler_init(void)
Initialize the error handler interface.
Definition: errhandler.c:75
Main top-level request struct definition.
Definition: request.h:100
ompi_errhandler_type_t
Enum used to describe what kind MPI object an error handler is used for.
Definition: errhandler.h:84