OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

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"
34 #include "opal/class/opal_pointer_array.h"
35
36 #include "ompi/runtime/mpiruntime.h"
37 #include "ompi/errhandler/errhandler_predefined.h"
38 #include "ompi/errhandler/errcode-internal.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 */
73 enum ompi_errhandler_lang_t {
74 OMPI_ERRHANDLER_LANG_C,
75 OMPI_ERRHANDLER_LANG_CXX,
76 OMPI_ERRHANDLER_LANG_FORTRAN
77 };
78 typedef enum ompi_errhandler_lang_t ompi_errhandler_lang_t;
79
80
81 /**
82 * Enum used to describe what kind MPI object an error handler is used for
83 */
84 enum ompi_errhandler_type_t {
85 OMPI_ERRHANDLER_TYPE_PREDEFINED,
86 OMPI_ERRHANDLER_TYPE_COMM,
87 OMPI_ERRHANDLER_TYPE_WIN,
88 OMPI_ERRHANDLER_TYPE_FILE
89 };
90 typedef enum ompi_errhandler_type_t ompi_errhandler_type_t;
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 */
108 struct ompi_errhandler_t {
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;
126 ompi_errhandler_fortran_handler_fn_t *eh_fort_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
148 struct ompi_predefined_errhandler_t {
149 struct ompi_errhandler_t eh;
150 char padding[PREDEFINED_ERRHANDLER_PAD - sizeof(ompi_errhandler_t)];
151 };
152
153 typedef struct ompi_predefined_errhandler_t ompi_predefined_errhandler_t;
154
155
156 /**
157 * Global variable for MPI_ERRHANDLER_NULL
158 */
159 OMPI_DECLSPEC extern ompi_predefined_errhandler_t ompi_mpi_errhandler_null;
160
161 /**
162 * Global variable for MPI_ERRORS_ARE_FATAL
163 */
164 OMPI_DECLSPEC extern ompi_predefined_errhandler_t ompi_mpi_errors_are_fatal;
165
166 /**
167 * Global variable for MPI_ERRORS_RETURN
168 */
169 OMPI_DECLSPEC extern ompi_predefined_errhandler_t ompi_mpi_errors_return;
170
171 /**
172 * Global variable for MPI::ERRORS_THROW_EXCEPTIONS. Will abort if
173 * MPI_INIT wasn't called as MPI::INIT
174 */
175 OMPI_DECLSPEC extern ompi_predefined_errhandler_t ompi_mpi_errors_throw_exceptions;
176
177 /**
178 * Table for Fortran <-> C errhandler handle conversion
179 */
180 OMPI_DECLSPEC extern opal_pointer_array_t ompi_errhandler_f_to_c_table;
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 */
367 OMPI_DECLSPEC ompi_errhandler_t *ompi_errhandler_create(ompi_errhandler_type_t object_type,
368 ompi_errhandler_generic_handler_fn_t *func,
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_mpi_errhandler_null
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errhandler_null
Global variable for MPI_ERRHANDLER_NULL.
Definition: errhandler.c:57
opal_pointer_array_t
dynamic pointer array
Definition: opal_pointer_array.h:45
ompi_predefined_errhandler_t
Definition: errhandler.h:148
ompi_errhandler_t
Back-end type for MPI_Errorhandler.
Definition: errhandler.h:108
ompi_mpi_errors_are_fatal
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errors_are_fatal
Global variable for MPI_ERRORS_ARE_FATAL.
Definition: errhandler.c:58
opal_pointer_array.h
See opal_bitmap.h for an explanation of why there is a split between OPAL and ORTE for this generic c...
proc.h
Process identification structure interface.
ompi_proc_t
Remote Open MPI process structure.
Definition: proc.h:56
types.h
ompi_errhandler_is_intrinsic
static bool ompi_errhandler_is_intrinsic(ompi_errhandler_t *errhandler)
Check to see if an errhandler is intrinsic.
Definition: errhandler.h:396
ompi_errhandler_generic_handler_fn_t
void( ompi_errhandler_generic_handler_fn_t)(void *, int *,...)
Typedef for generic errhandler function.
Definition: errhandler.h:68
errcode-internal.h
ompi_errhandler_runtime_callback
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
mpiruntime.h
Interface into the MPI portion of the Open MPI Run Time Environment.
ompi_errhandler_lang_t
ompi_errhandler_lang_t
Enum to denote what language the error handler was created from.
Definition: errhandler.h:73
ompi_errhandler_cxx_dispatch_fn_t
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
ompi_errhandler_request_invoke
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
opal_object_t
Base object.
Definition: opal_object.h:182
ompi_errhandler_create
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
ompi_errhandler_fortran_handler_fn_t
void( ompi_errhandler_fortran_handler_fn_t)(MPI_Fint *, MPI_Fint *,...)
Typedef for all fortran errhandler functions.
Definition: errhandler.h:62
ompi_mpi_errors_throw_exceptions
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errors_throw_exceptions
Global variable for MPI::ERRORS_THROW_EXCEPTIONS.
Definition: errhandler.c:60
ompi_errhandler_f_to_c_table
OMPI_DECLSPEC opal_pointer_array_t ompi_errhandler_f_to_c_table
Table for Fortran <-> C errhandler handle conversion.
Definition: errhandler.c:40
PREDEFINED_ERRHANDLER_PAD
#define PREDEFINED_ERRHANDLER_PAD
Padded struct to maintain back compatibiltiy.
Definition: errhandler.h:146
prefetch.h
Compiler-specific prefetch functions.
ompi_errhandler_finalize
int ompi_errhandler_finalize(void)
Finalize the error handler interface.
Definition: errhandler.c:158
ompi_mpi_errors_return
OMPI_DECLSPEC ompi_predefined_errhandler_t ompi_mpi_errors_return
Global variable for MPI_ERRORS_RETURN.
Definition: errhandler.c:59
opal_object.h
A simple C-language object-oriented system with single inheritance and ownership-based memory managem...
ompi_errhandler_init
int ompi_errhandler_init(void)
Initialize the error handler interface.
Definition: errhandler.c:75
ompi_request_t
Main top-level request struct definition.
Definition: request.h:100
ompi_errhandler_type_t
ompi_errhandler_type_t
Enum used to describe what kind MPI object an error handler is used for.
Definition: errhandler.h:84