-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpi/errhan/errutil.c
-: 0:Graph:errutil.gcno
-: 0:Data:errutil.gcda
-: 0:Runs:4383
-: 0:Programs:1376
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: *
-: 4: * (C) 2001 by Argonne National Laboratory.
-: 5: * See COPYRIGHT in top-level directory.
-: 6: */
-: 7:
-: 8:/* style: allow:fprintf:4 sig:0 */
-: 9:
-: 10:/* stdarg is required to handle the variable argument lists for
|
-: 11: MPIR_Err_create_code */
-: 12:#include <stdarg.h>
-: 13:/* Define USE_ERR_CODE_VALIST to get the prototype for the valist version
-: 14: of MPIR_Err_create_code in mpierror.h (without this definition,
-: 15: the prototype is not included. The "valist" version of the function
-: 16: is used in only a few places, here and potentially in ROMIO) */
-: 17:#define USE_ERR_CODE_VALIST
-: 18:
-: 19:#include "mpiimpl.h"
-: 20:/* errcodes.h contains the macros used to access fields within an error
-: 21: code and a description of the bits in an error code. A brief
-: 22: version of that description is included below */
-: 23:
-: 24:#include "errcodes.h"
-: 25:
-: 26:/* defmsg is generated automatically from the source files and contains
-: 27: all of the error messages, both the generic and specific. Depending
-: 28: on the value of MPICH_ERROR_MSG_LEVEL, different amounts of message
-: 29: information will be included from the file defmsg.h */
-: 30:#include "defmsg.h"
-: 31:
-: 32:/* stdio is needed for vsprintf and vsnprintf */
-: 33:#include <stdio.h>
-: 34:
-: 35:/* TEMP TO KEEP COMPILER HAPPY */
-: 36:void MPIR_Err_print_stack_string_ext(int errcode, char *str, int maxlen,
-: 37: MPIR_Err_get_class_string_func_t fn);
-: 38:
-: 39:/*
-: 40: * Structure of this file
-: 41: *
-: 42: * This file contains several groups of routines user for error handling
-: 43: * and reporting.
-: 44: *
-: 45: * The first group provides memory for the MPID_Errhandler objects
-: 46: * and the routines to free and manipulate them
-: 47: *
-: 48: * MPIR_Err_return_xxx - For each of the MPI types on which an
-: 49: * error handler can be defined, there is an MPIR_Err_return_xxx routine
-: 50: * that determines what error handler function to call and whether to
-: 51: * abort the program. The comm and win versions are here; ROMIO
-: 52: * provides its own routines for invoking the error handlers for Files.
-: 53: *
-: 54: * The next group of code handles the error messages. There are three
-: 55: * options, controlled by the value of MPICH_ERROR_MSG_LEVEL.
-: 56: *
-: 57: * MPICH_ERROR_MSG_NONE - No text messages at all
-: 58: * MPICH_ERROR_MSG_CLASS - Only messages for the MPI error classes
-: 59: * MPICH_ERROR_MSG_GENERIC - Only predefiend messages for the MPI error codes
-: 60: * MPICH_ERROR_MSG_ALL - Instance specific error messages (and error message
-: 61: * stack)
-: 62: *
-: 63: * In only the latter (MPICH_ERROR_MSG_ALL) case are instance-specific
-: 64: * messages maintained (including the error message "stack" that you may
-: 65: * see mentioned in various places. In the other cases, an error code
-: 66: * identifies a fixed message string (unless MPICH_ERROR_MSG_NONE,
-: 67: * when there are no strings) from the "generic" strings defined in defmsg.h
-: 68: *
-: 69: * A major subgroup in this section is the code to handle the instance-specific
-: 70: * messages (MPICH_ERROR_MSG_ALL only).
-: 71: *
-: 72: * An MPI error code is made up of a number of fields (see errcodes.h)
-: 73: * These ar
-: 74: * is-dynamic? specific-msg-sequence# specific-msg-index
-: 75: * generic-code is-fatal? class
-: 76: *
-: 77: * There are macros (defined in errcodes.h) that define these fields,
-: 78: * their sizes, and masks and shifts that may be used to extract them.
-: 79: */
-: 80:
-: 81:/* A few prototypes. These routines are called from the MPIR_Err_return
-: 82: routines. checkValidErrcode depends on the MPICH_ERROR_MSG_LEVEL */
-: 83:
-: 84:static int checkValidErrcode( int error_class, const char fcname[],
-: 85: int *errcode );
-: 86:static void handleFatalError( MPID_Comm *comm_ptr,
-: 87: const char fcname[], int errcode );
-: 88:
-: 89:#if MPICH_ERROR_MSG_LEVEL >= MPICH_ERROR_MSG_ALL
-: 90:static int ErrGetInstanceString( int errorcode, char *msg, int num_remaining,
-: 91: MPIR_Err_get_class_string_func_t fn );
-: 92:static void MPIR_Err_stack_init( void );
-: 93:static int checkForUserErrcode( int errcode );
-: 94:#else
-: 95:/* We only need special handling for user error codes when we support the
-: 96: error message stack */
-: 97:#define checkForUserErrcode(_a) _a
-: 98:#endif
-: 99:
-: 100:
-: 101:/* ------------------------------------------------------------------------- */
-: 102:/* Provide the MPID_Errhandler space and the routines to free and set them
-: 103: from C++ */
-: 104:/* ------------------------------------------------------------------------- */
-: 105:/*
-: 106: * Error handlers. These are handled just like the other opaque objects
-: 107: * in MPICH
-: 108: */
-: 109:
-: 110:#ifndef MPID_ERRHANDLER_PREALLOC
-: 111:#define MPID_ERRHANDLER_PREALLOC 8
-: 112:#endif
-: 113:
-: 114:/* Preallocated errorhandler objects */
-: 115:MPID_Errhandler MPID_Errhandler_builtin[3] = {
-: 116: { MPIU_OBJECT_HEADER_INITIALIZER(MPI_ERRORS_ARE_FATAL, 0), },
-: 117: { MPIU_OBJECT_HEADER_INITIALIZER(MPI_ERRORS_RETURN, 0), },
-: 118: { MPIU_OBJECT_HEADER_INITIALIZER(MPIR_ERRORS_THROW_EXCEPTIONS, 0) },
-: 119: };
-: 120:MPID_Errhandler MPID_Errhandler_direct[MPID_ERRHANDLER_PREALLOC] = { { MPIU_OBJECT_HEADER_INITIALIZER(0,0) } };
-: 121:MPIU_Object_alloc_t MPID_Errhandler_mem = { 0, 0, 0, 0, MPID_ERRHANDLER,
-: 122: sizeof(MPID_Errhandler),
-: 123: MPID_Errhandler_direct,
-: 124: MPID_ERRHANDLER_PREALLOC, };
-: 125:
-: 126:void MPID_Errhandler_free(MPID_Errhandler *errhan_ptr)
|
10: 127:{
10: 128: MPIU_Handle_obj_free(&MPID_Errhandler_mem, errhan_ptr);
10: 129:}
-: 130:
-: 131:#ifdef HAVE_CXX_BINDING
-: 132:/* This routine is used to install a callback used by the C++ binding
-: 133: to invoke the (C++) error handler. The callback routine is a C routine,
-: 134: defined in the C++ binding. */
-: 135:void MPIR_Errhandler_set_cxx( MPI_Errhandler errhand, void (*errcall)(void) )
6: 136:{
-: 137: MPID_Errhandler *errhand_ptr;
-: 138:
6: 139: MPID_Errhandler_get_ptr( errhand, errhand_ptr );
6: 140: errhand_ptr->language = MPID_LANG_CXX;
6: 141: MPIR_Process.cxx_call_errfn = (void (*)( int, int *, int *,
-: 142: void (*)(void) ))errcall;
6: 143:}
-: 144:#endif
-: 145:
-: 146:/* ------------------------------------------------------------------------- */
-: 147:/*
-: 148: Nesting level for routines.
-: 149: Note that since these use per-thread data, no locks or atomic update
-: 150: routines are required.
-: 151:
-: 152: In a single-threaded environment, these are replaced with
-: 153: MPIR_Thread.nest_count ++, --. These are defined in the mpiimpl.h file.
-: 154: */
-: 155:/* ------------------------------------------------------------------------- */
-: 156:
-: 157:/* These routines export the nest increment and decrement for use in ROMIO */
-: 158:void MPIR_Nest_incr_export( void )
3379773: 159:{
3379773: 160: MPIU_THREADPRIV_DECL;
3379773: 161: MPIU_THREADPRIV_GET;
3379773: 162: MPIU_THREADPRIV_FIELD(nest_count) = MPIU_THREADPRIV_FIELD(nest_count) + 1;
3379773: 163:}
-: 164:void MPIR_Nest_decr_export( void )
3379773: 165:{
3379773: 166: MPIU_THREADPRIV_DECL;
3379773: 167: MPIU_THREADPRIV_GET;
3379773: 168: MPIU_THREADPRIV_FIELD(nest_count) = MPIU_THREADPRIV_FIELD(nest_count) - 1;
3379773: 169:}
-: 170:#ifdef MPICH_DEBUG_NESTING
-: 171:void MPIR_Nest_incr_export_dbg( const char *srcfile, int srcline )
-: 172:{
-: 173: MPIU_THREADPRIV_DECL;
-: 174: MPIU_THREADPRIV_GET;
-: 175:
-: 176: if (MPIU_THREADPRIV_FIELD(nest_count) >= MPICH_MAX_NESTINFO) {
-: 177: MPIU_Internal_error_printf("nest stack exceeded at %s:%d\n",
-: 178: srcfile, srcline );
-: 179: }
-: 180: else {
-: 181: MPIU_Strncpy(MPIU_THREADPRIV_FIELD(nestinfo)[MPIU_THREADPRIV_FIELD(nest_count)].file,srcfile, MPICH_MAX_NESTFILENAME);
-: 182: MPIU_THREADPRIV_FIELD(nestinfo)[MPIU_THREADPRIV_FIELD(nest_count)].line=srcline;
-: 183: }
-: 184: MPIU_THREADPRIV_FIELD(nest_count)++;
-: 185:}
-: 186:void MPIR_Nest_decr_export_dbg( const char *srcfile, int srcline )
-: 187:{
-: 188: MPIU_THREADPRIV_DECL;
-: 189: MPIU_THREADPRIV_GET;
-: 190:
-: 191: if (MPIU_THREADPRIV_FIELD(nest_count) >= 0) {
-: 192: MPIU_THREADPRIV_FIELD(nestinfo)[MPIU_THREADPRIV_FIELD(nest_count)].line=-srcline;}
-: 193: MPIU_THREADPRIV_FIELD(nest_count)--;
-: 194: if (MPIU_THREADPRIV_FIELD(nest_count) < MPICH_MAX_NESTINFO &&
-: 195: strcmp(MPIU_THREADPRIV_FIELD(nestinfo)[MPIU_THREADPRIV_FIELD(nest_count)].file,srcfile) != 0) {
-: 196: MPIU_Msg_printf( "Decremented nest count in file %s:%d but incremented in different file (%s:%d)\n",
-: 197: srcfile, srcline,
-: 198: MPIU_THREADPRIV_FIELD(nestinfo)[MPIU_THREADPRIV_FIELD(nest_count)].file, \
-: 199: MPIU_THREADPRIV_FIELD(nestinfo)[MPIU_THREADPRIV_FIELD(nest_count)].line);\
-: 200: }
-: 201: else if (MPIU_THREADPRIV_FIELD(nest_count) < 0) {
-: 202: MPIU_Msg_printf("Decremented nest count in file %s:%d is negative\n",
-: 203: srcfile,srcline);
-: 204: }
-: 205:}
-: 206:#endif
-: 207:/* ------------------------------------------------------------------------- */
-: 208:/* These routines are called on error exit from most top-level MPI routines
-: 209: to invoke the appropriate error handler. Also included is the routine
-: 210: to call if MPI has not been initialized (MPIR_Err_preinit) and to
-: 211: determine if an error code represents a fatal error (MPIR_Err_is_fatal). */
-: 212:/* ------------------------------------------------------------------------- */
-: 213:/* Special error handler to call if we are not yet initialized, or if we
-: 214: have finalized */
-: 215:void MPIR_Err_preOrPostInit( void )
2: 216:{
2: 217: if (MPIR_Process.initialized == MPICH_PRE_INIT) {
|
#####: 218: MPIU_Error_printf("Attempting to use an MPI routine before initializing MPICH\n");
-: 219: }
|
2: 220: else if (MPIR_Process.initialized == MPICH_POST_FINALIZED) {
2: 221: MPIU_Error_printf("Attempting to use an MPI routine after finalizing MPICH\n");
-: 222: }
-: 223: else {
|
#####: 224: MPIU_Error_printf("Internal Error: Unknown state of MPI (neither initialized nor finalized)\n" );
-: 225: }
|
2: 226: exit(1);
-: 227:}
-: 228:
-: 229:/* Return true if the error code indicates a fatal error */
-: 230:int MPIR_Err_is_fatal(int errcode)
16328608: 231:{
16328608: 232: return (errcode & ERROR_FATAL_MASK) ? TRUE : FALSE;
-: 233:}
-: 234:
-: 235:/*
-: 236: * This is the routine that is invoked by most MPI routines to
-: 237: * report an error. It is legitimate to pass NULL for comm_ptr in order to get
-: 238: * the default (MPI_COMM_WORLD) error handling.
-: 239: */
|
-: 240:int MPIR_Err_return_comm( MPID_Comm *comm_ptr, const char fcname[],
-: 241: int errcode )
|
6951: 242:{
6951: 243: const int error_class = ERROR_GET_CLASS(errcode);
-: 244: int rc;
6951: 245: MPIU_THREADPRIV_DECL;
-: 246:
6951: 247: MPIU_THREADPRIV_GET;
-: 248:
6951: 249: rc = checkValidErrcode( error_class, fcname, &errcode );
-: 250:
-: 251: /* First, check the nesting level */
6951: 252: if (MPIR_Nest_value()) return errcode;
-: 253:
|
-: 254: MPIU_DBG_MSG_FMT(ERRHAND, TERSE, (MPIU_DBG_FDEST, "MPIR_Err_return_comm(comm_ptr=%p, fcname=%s, errcode=%d)", comm_ptr, fcname, errcode));
-: 255:
|
6937: 256: if (!comm_ptr || comm_ptr->errhandler == NULL) {
-: 257: /* Try to replace with the default handler, which is the one on
-: 258: MPI_COMM_WORLD. This gives us correct behavior for the
-: 259: case where the error handler on MPI_COMM_WORLD has been changed. */
373: 260: if (MPIR_Process.comm_world)
-: 261: {
373: 262: comm_ptr = MPIR_Process.comm_world;
-: 263: }
-: 264: }
-: 265:
6937: 266: if (MPIR_Err_is_fatal(errcode) ||
-: 267: comm_ptr == NULL || comm_ptr->errhandler == NULL ||
-: 268: comm_ptr->errhandler->handle == MPI_ERRORS_ARE_FATAL) {
-: 269: /* Calls MPID_Abort */
5: 270: handleFatalError( comm_ptr, fcname, errcode );
-: 271: }
-: 272:
-: 273: /* Check for the special case of a user-provided error code */
6932: 274: errcode = checkForUserErrcode( errcode );
-: 275:
6932: 276: if (comm_ptr->errhandler->handle == MPI_ERRORS_RETURN ||
-: 277: comm_ptr->errhandler->handle == MPIR_ERRORS_THROW_EXCEPTIONS)
-: 278: {
6909: 279: return errcode;
-: 280: }
-: 281: else
-: 282: {
-: 283: /* The user error handler may make calls to MPI routines, so the
-: 284: * nesting counter must be incremented before the handler is called */
23: 285: MPIR_Nest_incr();
-: 286:
-: 287: /* We pass a final 0 (for a null pointer) to these routines
-: 288: because MPICH-1 expected that */
23: 289: switch (comm_ptr->errhandler->language)
-: 290: {
-: 291: case MPID_LANG_C:
22: 292: (*comm_ptr->errhandler->errfn.C_Comm_Handler_function)(
-: 293: &comm_ptr->handle, &errcode, 0 );
22: 294: break;
-: 295:#ifdef HAVE_CXX_BINDING
-: 296: case MPID_LANG_CXX:
1: 297: (*MPIR_Process.cxx_call_errfn)( 0, &comm_ptr->handle, &errcode,
-: 298: (void (*)(void))*comm_ptr->errhandler->errfn.C_Comm_Handler_function );
-: 299: /* The C++ code throws an exception if the error handler
-: 300: returns something other than MPI_SUCCESS. There is no "return"
-: 301: of an error code. */
1: 302: errcode = MPI_SUCCESS;
1: 303: break;
-: 304:#endif
-: 305:#ifdef HAVE_FORTRAN_BINDING
-: 306: case MPID_LANG_FORTRAN90:
-: 307: case MPID_LANG_FORTRAN:
|
#####: 308: (*comm_ptr->errhandler->errfn.F77_Handler_function)(
-: 309: (MPI_Fint *)&comm_ptr->handle, &errcode );
-: 310: break;
-: 311:#endif
-: 312: }
-: 313:
|
23: 314: MPIR_Nest_decr();
-: 315: }
23: 316: return errcode;
-: 317:}
-: 318:
-: 319:/*
-: 320: * MPI routines that detect errors on window objects use this to report errors
-: 321: */
|
-: 322:int MPIR_Err_return_win( MPID_Win *win_ptr, const char fcname[], int errcode )
|
8: 323:{
8: 324: const int error_class = ERROR_GET_CLASS(errcode);
-: 325: int rc ;
8: 326: MPIU_THREADPRIV_DECL;
-: 327:
8: 328: MPIU_THREADPRIV_GET;
-: 329:
8: 330: if (win_ptr == NULL || win_ptr->errhandler == NULL)
|
2: 331: return MPIR_Err_return_comm(NULL, fcname, errcode);
-: 332:
|
6: 333: rc = checkValidErrcode( error_class, fcname, &errcode );
-: 334:
-: 335: /* First, check the nesting level */
6: 336: if (MPIR_Nest_value()) return errcode;
-: 337:
|
-: 338: MPIU_DBG_MSG_FMT(ERRHAND, TERSE, (MPIU_DBG_FDEST, "MPIR_Err_return_win(win_ptr=%p, fcname=%s, errcode=%d)", win_ptr, fcname, errcode));
-: 339:
|
6: 340: if (MPIR_Err_is_fatal(errcode) ||
-: 341: win_ptr == NULL || win_ptr->errhandler == NULL ||
-: 342: win_ptr->errhandler->handle == MPI_ERRORS_ARE_FATAL) {
-: 343: /* Calls MPID_Abort */
|
#####: 344: handleFatalError( NULL, fcname, errcode );
-: 345: }
-: 346:
-: 347: /* Check for the special case of a user-provided error code */
|
6: 348: errcode = checkForUserErrcode( errcode );
-: 349:
6: 350: if (win_ptr->errhandler->handle == MPI_ERRORS_RETURN ||
-: 351: win_ptr->errhandler->handle == MPIR_ERRORS_THROW_EXCEPTIONS)
-: 352: {
|
#####: 353: return errcode;
-: 354: }
-: 355: else
-: 356: {
-: 357: /* Now, invoke the error handler for the window */
-: 358:
-: 359: /* The user error handler may make calls to MPI routines, so the
-: 360: * nesting counter must be incremented before the handler is called */
|
6: 361: MPIR_Nest_incr();
-: 362:
-: 363: /* We pass a final 0 (for a null pointer) to these routines
-: 364: because MPICH-1 expected that */
6: 365: switch (win_ptr->errhandler->language)
-: 366: {
-: 367: case MPID_LANG_C:
6: 368: (*win_ptr->errhandler->errfn.C_Win_Handler_function)(
-: 369: &win_ptr->handle, &errcode, 0 );
6: 370: break;
-: 371:#ifdef HAVE_CXX_BINDING
-: 372: case MPID_LANG_CXX:
|
#####: 373: (*MPIR_Process.cxx_call_errfn)( 2, &win_ptr->handle, &errcode,
-: 374: (void (*)(void))*win_ptr->errhandler->errfn.C_Win_Handler_function );
-: 375: /* The C++ code throws an exception if the error handler
-: 376: returns something other than MPI_SUCCESS. There is no "return"
-: 377: of an error code. */
#####: 378: errcode = MPI_SUCCESS;
#####: 379: break;
-: 380:#endif
-: 381:#ifdef HAVE_FORTRAN_BINDING
-: 382: case MPID_LANG_FORTRAN90:
-: 383: case MPID_LANG_FORTRAN:
#####: 384: (*win_ptr->errhandler->errfn.F77_Handler_function)(
-: 385: (MPI_Fint *)&win_ptr->handle, &errcode );
-: 386: break;
-: 387:#endif
-: 388: }
-: 389:
|
6: 390: MPIR_Nest_decr();
-: 391: }
6: 392: return errcode;
-: 393:}
-: 394:
-: 395:
-: 396:/* ------------------------------------------------------------------------- */
-: 397:/* ------------------------------------------------------------------------- */
-: 398:static int convertErrcodeToIndexes( int errcode, int *ring_idx, int *ring_id,
-: 399: int *generic_idx );
-: 400:static int checkErrcodeIsValid( int errcode );
-: 401:static const char *ErrcodeInvalidReasonStr( int reason );
-: 402:static const char *get_class_msg( int error_class );
-: 403:
-: 404:
-: 405:void MPIR_Err_init( void )
4383: 406:{
-: 407:# if MPICH_ERROR_MSG_LEVEL >= MPICH_ERROR_MSG_ALL
4383: 408: MPIR_Err_stack_init();
-: 409:# endif
4383: 410:}
-: 411:
-: 412:
-: 413:/* ------------------------------------------------------------------------- */
-: 414:/* The following block of code manages the instance-specific error messages */
-: 415:/* ------------------------------------------------------------------------- */
-: 416:
-: 417:
-: 418:/* Check for a valid error code. If the code is not valid, attempt to
-: 419: print out something sensible; reset the error code to have class
-: 420: ERR_UNKNOWN */
-: 421:/* FIXME: Now that error codes are chained, this does not produce a valid
-: 422: error code since there is no valid ring index corresponding to this code */
-: 423:static int checkValidErrcode( int error_class, const char fcname[],
-: 424: int *errcode_p )
6957: 425:{
6957: 426: int errcode = *errcode_p;
6957: 427: int rc = 0;
-: 428:
6957: 429: if (error_class > MPICH_ERR_LAST_CLASS)
-: 430: {
|
#####: 431: if (errcode & ~ERROR_CLASS_MASK)
-: 432: {
#####: 433: MPIU_Error_printf("INTERNAL ERROR: Invalid error class (%d) encountered while returning from\n"
-: 434: "%s. Please file a bug report.\n", error_class, fcname);
-: 435: /* Note that we don't try to print the error stack; if the
-: 436: error code is invalid, it can't be used to find
-: 437: the error stack. We could consider dumping the
-: 438: contents of the error ring instead (without trying
-: 439: to interpret them) */
-: 440: }
-: 441: else
-: 442: {
#####: 443: MPIU_Error_printf("INTERNAL ERROR: Invalid error class (%d) encountered while returning from\n"
-: 444: "%s. Please file a bug report. No error stack is available.\n", error_class, fcname);
-: 445: }
-: 446: /* FIXME: We probably want to set this to MPI_ERR_UNKNOWN
-: 447: and discard the rest of the bits */
#####: 448: errcode = (errcode & ~ERROR_CLASS_MASK) | MPI_ERR_UNKNOWN;
#####: 449: rc = 1;
-: 450: }
|
6957: 451: *errcode_p = errcode;
6957: 452: return rc;
-: 453:}
-: 454:
-: 455:/* Check that an encoded error code is valid. Return 0 if valid, positive,
-: 456: non-zero if invalid. Value indicates reason; see
-: 457: ErrcodeInvalidReasonStr() */
-: 458:
-: 459:#if MPICH_ERROR_MSG_LEVEL <= MPICH_ERROR_MSG_GENERIC
-: 460:/* This is the shortened version when there are no error messages */
-: 461:static int checkErrcodeIsValid( int errcode )
-: 462:{
-: 463: /* MPICH_ERR_LAST_CLASS is the last of the *predefined* error classes. */
-: 464: /* FIXME: Should this check against dynamically-created error classes? */
-: 465: if (errcode < 0 || errcode >= MPICH_ERR_LAST_CLASS) {
-: 466: return 3;
-: 467: }
-: 468: return 0;
-: 469:}
-: 470:static const char *ErrcodeInvalidReasonStr( int reason )
-: 471:{
-: 472: const char *str = 0;
-: 473:
-: 474: /* FIXME: These strings need to be internationalized */
-: 475: switch (reason) {
-: 476: case 3:
-: 477: str = "Message class is out of range";
-: 478: break;
-: 479: default:
-: 480: str = "Unknown reason for invalid errcode";
-: 481: break;
-: 482: }
-: 483: return str;
-: 484:}
-: 485:#endif
-: 486:
-: 487:/* This routine is called when there is a fatal error */
-: 488:static void handleFatalError( MPID_Comm *comm_ptr,
-: 489: const char fcname[], int errcode )
5: 490:{
-: 491: /* Define length of the the maximum error message line (or string with
-: 492: newlines?). This definition is used only within this routine. */
-: 493: /* FIXME: This should really be the same as MPI_MAX_ERROR_STRING, or in the
-: 494: worst case, defined in terms of that */
-: 495:#define MAX_ERRMSG_STRING 4096
-: 496: char error_msg[ MAX_ERRMSG_STRING ];
-: 497: int len;
-: 498:
-: 499: /* FIXME: Not internationalized */
5: 500: MPIU_Snprintf(error_msg, MAX_ERRMSG_STRING, "Fatal error in %s: ", fcname);
5: 501: len = (int)strlen(error_msg);
5: 502: MPIR_Err_get_string(errcode, &error_msg[len], MAX_ERRMSG_STRING-len, NULL);
-: 503: /* The third argument is a return code, a value of 1 usually indicates
-: 504: an error */
5: 505: MPID_Abort(comm_ptr, MPI_SUCCESS, 1, error_msg);
|
#####: 506:}
-: 507:
-: 508:#if MPICH_ERROR_MSG_LEVEL >= MPICH_ERROR_MSG_GENERIC
-: 509:/*
-: 510: * Given a message string abbreviation (e.g., one that starts "**"), return
-: 511: * the corresponding index. For the generic (non
-: 512: * parameterized messages), use idx = FindGenericMsgIndex( "**msg" );
-: 513: */
-: 514:static int FindGenericMsgIndex( const char *msg )
|
10053: 515:{
-: 516: int i, c;
2599886: 517: for (i=0; i<generic_msgs_len; i++) {
-: 518: /* Check the sentinals to insure that the values are ok first */
2599886: 519: if (generic_err_msgs[i].sentinal1 != 0xacebad03 ||
-: 520: generic_err_msgs[i].sentinal2 != 0xcb0bfa11) {
-: 521: /* Something bad has happened! Don't risk trying the
-: 522: short_name pointer; it may have been corrupted */
-: 523: break;
-: 524: }
2599886: 525: c = strcmp( generic_err_msgs[i].short_name, msg );
2599886: 526: if (c == 0) return i;
2589833: 527: if (c > 0)
-: 528: {
-: 529: /* don't return here if the string partially matches */
|
#####: 530: if (strncmp(generic_err_msgs[i].short_name, msg, strlen(msg)) != 0)
#####: 531: return -1;
-: 532: }
-: 533: }
#####: 534: return -1;
-: 535:}
-: 536:
-: 537:/*
-: 538: Here is an alternate search routine based on bisection.
-: 539: int i_low, i_mid, i_high, c;
-: 540: i_low = 0; i_high = generic_msg_len - 1;
-: 541: while (i_high - i_low >= 0) {
-: 542: i_mid = (i_high + i_low) / 2;
-: 543: c = strcmp( generic_err_msgs[i].short_name, msg );
-: 544: if (c == 0) return i_mid;
-: 545: if (c < 0) { i_low = i_mid + 1; }
-: 546: else { i_high = i_mid - 1; }
-: 547: }
-: 548: return -1;
-: 549:*/
-: 550:#endif
-: 551:
-: 552:#if MPICH_ERROR_MSG_LEVEL == MPICH_ERROR_MSG_ALL
-: 553:/*
-: 554: * Given a message string abbreviation (e.g., one that starts "**"), return
-: 555: * the corresponding index. For the specific
-: 556: * (parameterized messages), use idx = FindSpecificMsgIndex( "**msg" );
-: 557: */
-: 558:static int FindSpecificMsgIndex( const char *msg )
|
9511: 559:{
-: 560: int i, c;
1437473: 561: for (i=0; i<specific_msgs_len; i++) {
-: 562: /* Check the sentinals to insure that the values are ok first */
1437473: 563: if (specific_err_msgs[i].sentinal1 != 0xacebad03 ||
-: 564: specific_err_msgs[i].sentinal2 != 0xcb0bfa11) {
-: 565: /* Something bad has happened! Don't risk trying the
-: 566: short_name pointer; it may have been corrupted */
-: 567: break;
-: 568: }
1437473: 569: c = strcmp( specific_err_msgs[i].short_name, msg );
1437473: 570: if (c == 0) return i;
1427962: 571: if (c > 0)
-: 572: {
-: 573: /* don't return here if the string partially matches */
|
#####: 574: if (strncmp(specific_err_msgs[i].short_name, msg, strlen(msg)) != 0)
#####: 575: return -1;
-: 576: }
-: 577: }
#####: 578: return -1;
-: 579:}
-: 580:/* See FindGenericMsgIndex comments for a more efficient search routine that
-: 581: could be used here as well. */
-: 582:#endif
-: 583:
-: 584:
-: 585:/* ------------------------------------------------------------------------ */
-: 586:/* The following routines create an MPI error code, handling optional, */
-: 587:/* instance-specific error message information. There are two key routines:*/
|
-: 588:/* MPIR_Err_create_code - Create the error code; this is the routine used*/
-: 589:/* by most routines */
-: 590:/* MPIR_Err_create_code_valist - Create the error code; accept a valist */
-: 591:/* instead of a variable argument list (this is */
-: 592:/* used to allow this routine to be used from */
-: 593:/* within another varargs routine) */
-: 594:/* ------------------------------------------------------------------------ */
-: 595:
-: 596:/* Err_create_code is just a shell that accesses the va_list and then
-: 597: calls the real routine. */
-: 598:int MPIR_Err_create_code( int lastcode, int fatal, const char fcname[],
-: 599: int line, int error_class, const char generic_msg[],
-: 600: const char specific_msg[], ... )
|
9293: 601:{
-: 602: int rc;
-: 603: va_list Argp;
9293: 604: va_start(Argp, specific_msg);
|
9293: 605: rc = MPIR_Err_create_code_valist( lastcode, fatal, fcname, line,
-: 606: error_class, generic_msg, specific_msg,
-: 607: Argp );
|
9293: 608: va_end(Argp);
9293: 609: return rc;
-: 610:}
-: 611:#if MPICH_ERROR_MSG_LEVEL < MPICH_ERROR_MSG_ALL
-: 612:/* In this case, the routine ignores all but (possibly) the generic message */
|
-: 613:int MPIR_Err_create_code_valist( int lastcode, int fatal, const char fcname[],
-: 614: int line, int error_class,
-: 615: const char generic_msg[],
-: 616: const char specific_msg[], va_list Argp )
-: 617:{
-: 618:#if MPICH_ERROR_MSG_LEVEL == MPICH_ERROR_MSG_GENERIC
-: 619: int generic_idx;
-: 620: int errcode;
-: 621: generic_idx = FindGenericMsgIndex(generic_msg);
-: 622: if (generic_idx >= 0) {
-: 623: errcode = (generic_idx << ERROR_GENERIC_SHIFT) | error_class;
-: 624: if (fatal)
-: 625: errcode |= ERROR_FATAL_MASK;
-: 626: }
-: 627: return errcode;
-: 628:#else
-: 629: return error_class;
-: 630:#endif
-: 631:}
-: 632:#endif /* msg_level < msg_all */
-: 633:
-: 634:/*
-: 635: * Accessor routines for the predefined mqessages. These can be
-: 636: * used by the other routines (such as MPI_Error_string) to
-: 637: * access the messages in this file, or the messages that may be
-: 638: * available through any message catalog facility
-: 639: */
-: 640:static const char *get_class_msg( int error_class )
|
1074: 641:{
-: 642:#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG_NONE
1074: 643: if (error_class >= 0 && error_class < MPIR_MAX_ERROR_CLASS_INDEX) {
1074: 644: return generic_err_msgs[class_to_index[error_class]].long_name;
-: 645: }
-: 646: else {
|
#####: 647: return "Unknown error class";
-: 648: }
-: 649:#else
-: 650: /* FIXME: Not internationalized */
-: 651: return "Error message texts are not available";
-: 652:#endif
-: 653:}
-: 654:
-: 655:/* FIXME: This routine isn't quite right yet */
-: 656:/*
-: 657: * Notes:
-: 658: * One complication is that in the instance-specific case, a
-: 659: */
-: 660:void MPIR_Err_get_string( int errorcode, char * msg, int length,
-: 661: MPIR_Err_get_class_string_func_t fn )
|
1273: 662:{
-: 663: int error_class;
1273: 664: int len, num_remaining = length;
-: 665:
1273: 666: if (num_remaining == 0)
|
#####: 667: num_remaining = MPI_MAX_ERROR_STRING;
-: 668:
-: 669: /* Convert the code to a string. The cases are:
-: 670: simple class. Find the corresponding string.
-: 671: <not done>
-: 672: if (user code) { go to code that extracts user error messages }
-: 673: else {
-: 674: is specific message code set and available? if so, use it
-: 675: else use generic code (lookup index in table of messages)
-: 676: }
-: 677: */
|
1273: 678: if (errorcode & ERROR_DYN_MASK) {
-: 679: /* This is a dynamically created error code (e.g., with
-: 680: MPI_Err_add_class) */
-: 681: /* If a dynamic error code was created, the function to convert
-: 682: them into strings has been set. Check to see that it was; this
-: 683: is a safeguard against a bogus error code */
199: 684: if (!MPIR_Process.errcode_to_string) {
-: 685: /* FIXME: not internationalized */
|
-: 686: /* --BEGIN ERROR HANDLING-- */
#####: 687: if (MPIU_Strncpy(msg, "Undefined dynamic error code",
-: 688: num_remaining))
-: 689: {
#####: 690: msg[num_remaining - 1] = '\0';
-: 691: }
-: 692: /* --END ERROR HANDLING-- */
-: 693: }
-: 694: else
-: 695: {
|
199: 696: if (MPIU_Strncpy(msg, MPIR_Process.errcode_to_string( errorcode ),
-: 697: num_remaining))
-: 698: {
|
#####: 699: msg[num_remaining - 1] = '\0';
-: 700: }
-: 701: }
-: 702: }
|
1074: 703: else if ( (errorcode & ERROR_CLASS_MASK) == errorcode) {
39: 704: error_class = MPIR_ERR_GET_CLASS(errorcode);
-: 705:
39: 706: if (fn != NULL && error_class > MPICH_ERR_LAST_CLASS /*&& error_class < MPICH_ERR_MAX_EXT_CLASS*/)
-: 707: {
|
#####: 708: fn(errorcode, msg, length);
-: 709: }
-: 710: else
-: 711: {
|
39: 712: if (MPIU_Strncpy(msg, get_class_msg( errorcode ), num_remaining))
-: 713: {
|
#####: 714: msg[num_remaining - 1] = '\0';
-: 715: }
-: 716: }
-: 717: }
-: 718: else
-: 719: {
-: 720: /* print the class message first */
|
1035: 721: error_class = MPIR_ERR_GET_CLASS(errorcode);
-: 722:
1035: 723: if (fn != NULL && error_class > MPICH_ERR_LAST_CLASS /*&& error_class < MPICH_ERR_MAX_EXT_CLASS*/)
-: 724: {
|
#####: 725: fn(errorcode, msg, num_remaining);
-: 726: }
-: 727: else
-: 728: {
|
1035: 729: MPIU_Strncpy(msg, get_class_msg(ERROR_GET_CLASS(errorcode)), num_remaining);
-: 730: }
1035: 731: msg[num_remaining - 1] = '\0';
1035: 732: len = (int)strlen(msg);
1035: 733: msg += len;
1035: 734: num_remaining -= len;
-: 735:
-: 736: /* then print the stack or the last specific error message */
-: 737:
-: 738:# if MPICH_ERROR_MSG_LEVEL >= MPICH_ERROR_MSG_ALL
1035: 739: if (ErrGetInstanceString( errorcode, msg, num_remaining, fn ))
1035: 740: goto fn_exit;
-: 741:#elif MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG_NONE
-: 742: {
-: 743: int generic_idx;
-: 744:
-: 745: generic_idx = ((errorcode & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT) - 1;
-: 746:
-: 747: if (generic_idx >= 0) {
-: 748: MPIU_Snprintf(msg, num_remaining, ", %s", generic_err_msgs[generic_idx].long_name);
-: 749: msg[num_remaining - 1] = '\0';
-: 750: goto fn_exit;
-: 751: }
-: 752: }
-: 753:# endif
-: 754: }
-: 755:
-: 756:fn_exit:
-: 757: return;
-: 758:}
-: 759:
-: 760:
-: 761:/* ------------------------------------------------------------------------- */
-: 762:/* Routines to convert instance-specific messages into a string */
-: 763:/* This is the only case that supports instance-specific messages */
-: 764:/* ------------------------------------------------------------------------- */
-: 765:/* ------------------------------------------------------------------------ */
-: 766:/* This block of code is used to convert various MPI values into descriptive*/
-: 767:/* strings. The routines are */
-: 768:/* GetAssertString - handle MPI_MODE_xxx (RMA asserts) */
-: 769:/* GetDTypeString - handle MPI_Datatypes */
-: 770:/* GetMPIOpString - handle MPI_Op */
-: 771:/* These routines are used in vsnprintf_mpi */
-: 772:/* FIXME: These functions are not thread safe */
-: 773:/* ------------------------------------------------------------------------ */
-: 774:#define ASSERT_STR_MAXLEN 256
-: 775:
-: 776:static const char * GetAssertString(int d)
|
#####: 777:{
-: 778: static char str[ASSERT_STR_MAXLEN] = "";
-: 779: char *cur;
#####: 780: size_t len = ASSERT_STR_MAXLEN;
-: 781: size_t n;
-: 782:
#####: 783: if (d == 0)
-: 784: {
#####: 785: MPIU_Strncpy(str, "assert=0", ASSERT_STR_MAXLEN);
#####: 786: return str;
-: 787: }
#####: 788: cur = str;
#####: 789: if (d & MPI_MODE_NOSTORE)
-: 790: {
#####: 791: MPIU_Strncpy(cur, "MPI_MODE_NOSTORE", len);
#####: 792: n = strlen(cur);
#####: 793: cur += n;
#####: 794: len -= n;
#####: 795: d ^= MPI_MODE_NOSTORE;
-: 796: }
#####: 797: if (d & MPI_MODE_NOCHECK)
-: 798: {
#####: 799: if (len < ASSERT_STR_MAXLEN)
#####: 800: MPIU_Strncpy(cur, " | MPI_MODE_NOCHECK", len);
-: 801: else
#####: 802: MPIU_Strncpy(cur, "MPI_MODE_NOCHECK", len);
#####: 803: n = strlen(cur);
#####: 804: cur += n;
#####: 805: len -= n;
#####: 806: d ^= MPI_MODE_NOCHECK;
-: 807: }
#####: 808: if (d & MPI_MODE_NOPUT)
-: 809: {
#####: 810: if (len < ASSERT_STR_MAXLEN)
#####: 811: MPIU_Strncpy(cur, " | MPI_MODE_NOPUT", len);
-: 812: else
#####: 813: MPIU_Strncpy(cur, "MPI_MODE_NOPUT", len);
#####: 814: n = strlen(cur);
#####: 815: cur += n;
#####: 816: len -= n;
#####: 817: d ^= MPI_MODE_NOPUT;
-: 818: }
#####: 819: if (d & MPI_MODE_NOPRECEDE)
-: 820: {
#####: 821: if (len < ASSERT_STR_MAXLEN)
#####: 822: MPIU_Strncpy(cur, " | MPI_MODE_NOPRECEDE", len);
-: 823: else
#####: 824: MPIU_Strncpy(cur, "MPI_MODE_NOPRECEDE", len);
#####: 825: n = strlen(cur);
#####: 826: cur += n;
#####: 827: len -= n;
#####: 828: d ^= MPI_MODE_NOPRECEDE;
-: 829: }
#####: 830: if (d & MPI_MODE_NOSUCCEED)
-: 831: {
#####: 832: if (len < ASSERT_STR_MAXLEN)
#####: 833: MPIU_Strncpy(cur, " | MPI_MODE_NOSUCCEED", len);
-: 834: else
#####: 835: MPIU_Strncpy(cur, "MPI_MODE_NOSUCCEED", len);
#####: 836: n = strlen(cur);
#####: 837: cur += n;
#####: 838: len -= n;
#####: 839: d ^= MPI_MODE_NOSUCCEED;
-: 840: }
#####: 841: if (d)
-: 842: {
#####: 843: if (len < ASSERT_STR_MAXLEN)
#####: 844: MPIU_Snprintf(cur, len, " | 0x%x", d);
-: 845: else
#####: 846: MPIU_Snprintf(cur, len, "assert=0x%x", d);
-: 847: }
#####: 848: return str;
-: 849:}
-: 850:
-: 851:static const char * GetDTypeString(MPI_Datatype d)
|
1803: 852:{
-: 853: static char default_str[64];
1803: 854: int num_integers, num_addresses, num_datatypes, combiner = 0;
-: 855: char *str;
-: 856:
1803: 857: if (HANDLE_GET_MPI_KIND(d) != MPID_DATATYPE || \
-: 858: (HANDLE_GET_KIND(d) == HANDLE_KIND_INVALID && \
-: 859: d != MPI_DATATYPE_NULL))
|
#####: 860: return "INVALID DATATYPE";
-: 861:
-: 862:
|
1803: 863: if (d == MPI_DATATYPE_NULL)
184: 864: return "MPI_DATATYPE_NULL";
-: 865:
1619: 866: if (d == 0)
-: 867: {
|
#####: 868: MPIU_Strncpy(default_str, "dtype=0x0", 64);
#####: 869: return default_str;
-: 870: }
-: 871:
|
1619: 872: MPID_Type_get_envelope(d, &num_integers, &num_addresses, &num_datatypes,
-: 873: &combiner);
1619: 874: if (combiner == MPI_COMBINER_NAMED)
-: 875: {
1606: 876: str = MPIDU_Datatype_builtin_to_string(d);
1606: 877: if (str == NULL)
-: 878: {
|
#####: 879: MPIU_Snprintf(default_str, 64, "dtype=0x%08x", d);
#####: 880: return default_str;
-: 881: }
|
1606: 882: return str;
-: 883: }
-: 884:
-: 885: /* default is not thread safe */
13: 886: str = MPIDU_Datatype_combiner_to_string(combiner);
13: 887: if (str == NULL)
-: 888: {
|
#####: 889: MPIU_Snprintf(default_str, 64, "dtype=USER<0x%08x>", d);
#####: 890: return default_str;
-: 891: }
|
13: 892: MPIU_Snprintf(default_str, 64, "dtype=USER<%s>", str);
13: 893: return default_str;
-: 894:}
-: 895:
-: 896:static const char * GetMPIOpString(MPI_Op o)
326: 897:{
-: 898: static char default_str[64];
-: 899:
326: 900: switch (o)
-: 901: {
-: 902: case MPI_OP_NULL:
78: 903: return "MPI_OP_NULL";
-: 904: case MPI_MAX:
18: 905: return "MPI_MAX";
-: 906: case MPI_MIN:
16: 907: return "MPI_MIN";
-: 908: case MPI_SUM:
50: 909: return "MPI_SUM";
-: 910: case MPI_PROD:
16: 911: return "MPI_PROD";
-: 912: case MPI_LAND:
16: 913: return "MPI_LAND";
-: 914: case MPI_BAND:
24: 915: return "MPI_BAND";
-: 916: case MPI_LOR:
16: 917: return "MPI_LOR";
-: 918: case MPI_BOR:
24: 919: return "MPI_BOR";
-: 920: case MPI_LXOR:
16: 921: return "MPI_LXOR";
-: 922: case MPI_BXOR:
24: 923: return "MPI_BXOR";
-: 924: case MPI_MINLOC:
14: 925: return "MPI_MINLOC";
-: 926: case MPI_MAXLOC:
14: 927: return "MPI_MAXLOC";
-: 928: case MPI_REPLACE:
|
#####: 929: return "MPI_REPLACE";
-: 930: }
-: 931: /* FIXME: default is not thread safe */
#####: 932: MPIU_Snprintf(default_str, 64, "op=0x%x", o);
#####: 933: return default_str;
-: 934:}
-: 935:
-: 936:/* ------------------------------------------------------------------------ */
-: 937:/* This routine takes an instance-specific string with format specifiers */
-: 938:/* This routine makes use of the above routines, along with some inlined */
-: 939:/* code, to process the format specifiers for the MPI objects */
-: 940:/* The current set of format specifiers is undocumented except for their
-: 941: use in this routine. In addition, these choices do not permit the
-: 942: use of GNU extensions to check the validity of these arguments.
-: 943: At some point, a documented set that can exploit those GNU extensions
-: 944: will replace these. */
-: 945:/* ------------------------------------------------------------------------ */
-: 946:
-: 947:static int vsnprintf_mpi(char *str, size_t maxlen, const char *fmt_orig,
-: 948: va_list list)
|
9461: 949:{
-: 950: char *begin, *end, *fmt;
-: 951: size_t len;
-: 952: MPI_Comm C;
-: 953: MPI_Info I;
-: 954: MPI_Datatype D;
-: 955: MPI_Win W;
-: 956: MPI_Group G;
-: 957: MPI_Op O;
-: 958: MPI_Request R;
-: 959: MPI_Errhandler E;
-: 960: char *s;
9461: 961: int t, i, d, mpi_errno=MPI_SUCCESS;
-: 962: long long ll;
-: 963: void *p;
-: 964:
9461: 965: fmt = MPIU_Strdup(fmt_orig);
9461: 966: if (fmt == NULL)
-: 967: {
|
#####: 968: if (maxlen > 0 && str != NULL)
#####: 969: *str = '\0';
#####: 970: return 0;
-: 971: }
-: 972:
|
9461: 973: begin = fmt;
9461: 974: end = strchr(fmt, '%');
44230: 975: while (end)
-: 976: {
25308: 977: len = maxlen;
25308: 978: if (len > (size_t)(end - begin)) {
25308: 979: len = (size_t)(end - begin);
-: 980: }
25308: 981: if (len)
-: 982: {
25308: 983: MPIU_Memcpy(str, begin, len);
25308: 984: str += len;
25308: 985: maxlen -= len;
-: 986: }
25308: 987: end++;
25308: 988: begin = end+1;
25308: 989: switch ((int)(*end))
-: 990: {
-: 991: case (int)'s':
1258: 992: s = va_arg(list, char *);
1258: 993: if (s)
1258: 994: MPIU_Strncpy(str, s, maxlen);
-: 995: else {
|
#####: 996: MPIU_Strncpy(str, "<NULL>", maxlen );
-: 997: }
-: 998: break;
-: 999: case (int)'d':
|
14332: 1000: d = va_arg(list, int);
14332: 1001: MPIU_Snprintf(str, maxlen, "%d", d);
14332: 1002: break;
-: 1003: case (int)'L':
|
#####: 1004: ll = va_arg(list, long long);
#####: 1005: MPIU_Snprintf(str, maxlen, "%lld", ll);
#####: 1006: break;
-: 1007: case (int)'x':
#####: 1008: d = va_arg(list, int);
#####: 1009: MPIU_Snprintf(str, maxlen, "%x", d);
#####: 1010: break;
-: 1011: case (int)'X':
#####: 1012: ll = va_arg(list, long long);
#####: 1013: MPIU_Snprintf(str, maxlen, "%llx", ll);
#####: 1014: break;
-: 1015: case (int)'i':
|
1280: 1016: i = va_arg(list, int);
1280: 1017: switch (i)
-: 1018: {
-: 1019: case MPI_ANY_SOURCE:
24: 1020: MPIU_Strncpy(str, "MPI_ANY_SOURCE", maxlen);
24: 1021: break;
-: 1022: case MPI_PROC_NULL:
46: 1023: MPIU_Strncpy(str, "MPI_PROC_NULL", maxlen);
46: 1024: break;
-: 1025: case MPI_ROOT:
14: 1026: MPIU_Strncpy(str, "MPI_ROOT", maxlen);
14: 1027: break;
-: 1028: default:
1196: 1029: MPIU_Snprintf(str, maxlen, "%d", i);
-: 1030: break;
-: 1031: }
-: 1032: break;
-: 1033: case (int)'t':
1280: 1034: t = va_arg(list, int);
1280: 1035: switch (t)
-: 1036: {
-: 1037: case MPI_ANY_TAG:
87: 1038: MPIU_Strncpy(str, "MPI_ANY_TAG", maxlen);
87: 1039: break;
-: 1040: case MPI_UNDEFINED:
|
#####: 1041: MPIU_Strncpy(str, "MPI_UNDEFINED", maxlen);
#####: 1042: break;
-: 1043: default:
|
1193: 1044: MPIU_Snprintf(str, maxlen, "%d", t);
-: 1045: break;
-: 1046: }
-: 1047: break;
-: 1048: case (int)'p':
3044: 1049: p = va_arg(list, void *);
-: 1050: /* FIXME: A check for MPI_IN_PLACE should only be used
-: 1051: where that is valid */
3044: 1052: if (p == MPI_IN_PLACE)
-: 1053: {
|
#####: 1054: MPIU_Strncpy(str, "MPI_IN_PLACE", maxlen);
-: 1055: }
-: 1056: else
-: 1057: {
-: 1058: /* FIXME: We may want to use 0x%p for systems that
-: 1059: (including Windows) that don't prefix %p with 0x.
-: 1060: This must be done with a capability, not a test on
-: 1061: particular OS or header files */
|
3044: 1062: MPIU_Snprintf(str, maxlen, "%p", p);
-: 1063: }
-: 1064: break;
-: 1065: case (int)'C':
1895: 1066: C = va_arg(list, MPI_Comm);
1895: 1067: switch (C)
-: 1068: {
-: 1069: case MPI_COMM_WORLD:
1563: 1070: MPIU_Strncpy(str, "MPI_COMM_WORLD", maxlen);
1563: 1071: break;
-: 1072: case MPI_COMM_SELF:
23: 1073: MPIU_Strncpy(str, "MPI_COMM_SELF", maxlen);
23: 1074: break;
-: 1075: case MPI_COMM_NULL:
151: 1076: MPIU_Strncpy(str, "MPI_COMM_NULL", maxlen);
151: 1077: break;
-: 1078: default:
158: 1079: MPIU_Snprintf(str, maxlen, "comm=0x%x", C);
-: 1080: break;
-: 1081: }
-: 1082: break;
-: 1083: case (int)'I':
2: 1084: I = va_arg(list, MPI_Info);
2: 1085: if (I == MPI_INFO_NULL)
-: 1086: {
2: 1087: MPIU_Strncpy(str, "MPI_INFO_NULL", maxlen);
-: 1088: }
-: 1089: else
-: 1090: {
|
#####: 1091: MPIU_Snprintf(str, maxlen, "info=0x%x", I);
-: 1092: }
-: 1093: break;
-: 1094: case (int)'D':
|
1803: 1095: D = va_arg(list, MPI_Datatype);
1803: 1096: MPIU_Snprintf(str, maxlen, "%s", GetDTypeString(D));
1803: 1097: break;
-: 1098: /* Include support for %F only if MPI-IO is enabled */
-: 1099:#ifdef MPI_MODE_RDWR
-: 1100: case (int)'F':
-: 1101: {
-: 1102: MPI_File F;
4: 1103: F = va_arg(list, MPI_File);
4: 1104: if (F == MPI_FILE_NULL)
-: 1105: {
|
#####: 1106: MPIU_Strncpy(str, "MPI_FILE_NULL", maxlen);
-: 1107: }
-: 1108: else
-: 1109: {
|
4: 1110: MPIU_Snprintf(str, maxlen, "file=0x%lx", (unsigned long)F);
-: 1111: }
-: 1112: }
-: 1113: break;
-: 1114:#endif
-: 1115: case (int)'W':
10: 1116: W = va_arg(list, MPI_Win);
10: 1117: if (W == MPI_WIN_NULL)
-: 1118: {
|
#####: 1119: MPIU_Strncpy(str, "MPI_WIN_NULL", maxlen);
-: 1120: }
-: 1121: else
-: 1122: {
|
10: 1123: MPIU_Snprintf(str, maxlen, "win=0x%x", W);
-: 1124: }
-: 1125: break;
-: 1126: case (int)'A':
|
#####: 1127: d = va_arg(list, int);
#####: 1128: MPIU_Snprintf(str, maxlen, "%s", GetAssertString(d));
#####: 1129: break;
-: 1130: case (int)'G':
|
64: 1131: G = va_arg(list, MPI_Group);
64: 1132: if (G == MPI_GROUP_NULL)
-: 1133: {
22: 1134: MPIU_Strncpy(str, "MPI_GROUP_NULL", maxlen);
-: 1135: }
-: 1136: else
-: 1137: {
42: 1138: MPIU_Snprintf(str, maxlen, "group=0x%x", G);
-: 1139: }
-: 1140: break;
-: 1141: case (int)'O':
326: 1142: O = va_arg(list, MPI_Op);
326: 1143: MPIU_Snprintf(str, maxlen, "%s", GetMPIOpString(O));
326: 1144: break;
-: 1145: case (int)'R':
|
#####: 1146: R = va_arg(list, MPI_Request);
#####: 1147: if (R == MPI_REQUEST_NULL)
-: 1148: {
#####: 1149: MPIU_Strncpy(str, "MPI_REQUEST_NULL", maxlen);
-: 1150: }
-: 1151: else
-: 1152: {
#####: 1153: MPIU_Snprintf(str, maxlen, "req=0x%x", R);
-: 1154: }
-: 1155: break;
-: 1156: case (int)'E':
|
10: 1157: E = va_arg(list, MPI_Errhandler);
10: 1158: if (E == MPI_ERRHANDLER_NULL)
-: 1159: {
2: 1160: MPIU_Strncpy(str, "MPI_ERRHANDLER_NULL", maxlen);
-: 1161: }
-: 1162: else
-: 1163: {
8: 1164: MPIU_Snprintf(str, maxlen, "errh=0x%x", E);
-: 1165: }
-: 1166: break;
-: 1167: default:
-: 1168: /* Error: unhandled output type */
|
#####: 1169: return 0;
-: 1170: /*
-: 1171: if (maxlen > 0 && str != NULL)
-: 1172: *str = '\0';
-: 1173: break;
-: 1174: */
-: 1175: }
|
25308: 1176: len = strlen(str);
25308: 1177: maxlen -= len;
25308: 1178: str += len;
25308: 1179: end = strchr(begin, '%');
-: 1180: }
9461: 1181: if (*begin != '\0')
-: 1182: {
2588: 1183: MPIU_Strncpy(str, begin, maxlen);
-: 1184: }
-: 1185: /* Free the dup'ed format string */
9461: 1186: MPIU_Free( fmt );
-: 1187:
9461: 1188: return mpi_errno;
-: 1189:}
-: 1190:
-: 1191:/* ------------------------------------------------------------------------- */
-: 1192:/* ------------------------------------------------------------------------- */
-: 1193:/*
-: 1194: * Instance-specific error messages are stored in a ring. The elements of this
-: 1195: * ring are MPIR_Err_msg_t structures, which contain the following fields:
-: 1196: * id - this is used to check that the entry is valid; it is computed from
-: 1197: * the error code and location in the ring. The routine
-: 1198: * ErrcodeToId( errcode, &id ) is used to extract the id from an
-: 1199: * error code and
-: 1200: * ErrcodeCreateID( class, generic, msg, &id, &seq ) is used to
-: 1201: * create the id from an error class, generic index, and message
-: 1202: * string. The "seq" field is inserted into the error code as a
-: 1203: * check.
-: 1204: *
-: 1205: * prev_error - The full MPI error code of the previous error attached
-: 1206: * to this list of errors, or MPI_SUCCESSS (which has value 0).
-: 1207: * This is the last error code, not the index in the ring of the last
-: 1208: * error code. That's the right choice, because we want to ensure
-: 1209: * that the value is valid if the ring overflows. In addition,
-: 1210: * we allow this to be an error CLASS (one of the predefined MPI
-: 1211: * error classes). This is particularly important for
-: 1212: * MPI_ERR_IN_STATUS, which may be returned as a valid error code.
-: 1213: * (classes are valid error codes).
-: 1214: *
-: 1215: * use_user_error_code and user_error_code - Used to handle a few cases
-: 1216: * in MPI where a user-provided routine returns an error code;
-: 1217: * this allows us to provide information about the chain of
-: 1218: * routines that were involved, while returning the users prefered
-: 1219: * error value to the users environment. See the note below
-: 1220: * on user error codes.
-: 1221: *
-: 1222: * location - A string that indicates what function and line number
-: 1223: * where the error code was set.
-: 1224: *
-: 1225: * msg - A message about the error. This may be instance-specific (e.g.,
-: 1226: * it may have been created at the time the error was detected with
-: 1227: * information about the parameters that caused the error).
-: 1228: *
-: 1229: * Note that both location and msg are defined as length MAX_xxx+1. This
-: 1230: * isn't really necessary (at least for msg), since the MPI standard
-: 1231: * requires that MAX_MPI_ERROR_STRING include the space for the trailing null,
-: 1232: * but using the extra byte makes the code a little simpler.
-: 1233: *
-: 1234: * The "id" value is used to keep a sort of "checkvalue" to ensure that the
-: 1235: * error code that points at this message is in fact for this particular
-: 1236: * message. This is used to handle the unlikely but possible situation where
-: 1237: * so many error messages are generated that the ring is overlapped.
-: 1238: *
-: 1239: * The message arrays are preallocated to ensure that there is space for these
-: 1240: * messages when an error occurs. One variation would be to allow these
-: 1241: * to be dynamically allocated, but it is probably better to either preallocate
-: 1242: * these or turn off all error message generation (which will eliminate these
-: 1243: * arrays).
-: 1244: *
-: 1245: * One possible alternative is to use the message ring *only* for instance
-: 1246: * messages and use the predefined messages in-place for the generic
-: 1247: * messages. The approach used here provides uniform handling of all
-: 1248: * error messages.
-: 1249: *
-: 1250: * Note on user error codes
-: 1251: *
-: 1252: * The "user error codes" is used to handle an ambiguity in the MPI-1
-: 1253: * standard about the return value from the attribute callbacks. The
-: 1254: * standard does not specify what values, other than 'MPI_SUCCESS', are
-: 1255: * valid. Because the Intel MPI-1 test suite expected 'MPI_Comm_dup' to
-: 1256: * return the same non-zero value returned by the attribute callback routine,
-: 1257: * this is the behavior that many (if not all) MPI implementations provide.
-: 1258: * As a result, the return from those routines is
-: 1259: *
-: 1260: */
-: 1261:#if MPICH_ERROR_MSG_LEVEL == MPICH_ERROR_MSG_ALL
-: 1262:
-: 1263:/* FIXME: Where is the documentation for this function? What is it for? */
-: 1264:static void MPIR_Err_print_stack_string(int errcode, char *str, int maxlen);
-: 1265:
-: 1266:#define MAX_ERROR_RING ERROR_SPECIFIC_INDEX_SIZE
-: 1267:#define MAX_LOCATION_LEN 63
-: 1268:
-: 1269:/* The maximum error string in this case may be a multi-line message,
-: 1270: constructed from multiple entries in the error message ring. The
-: 1271: individual ring messages should be shorter than MPI_MAX_ERROR_STRING,
-: 1272: perhaps as small a 256. We define a separate value for the error lines.
-: 1273: */
-: 1274:#define MPIR_MAX_ERROR_LINE 256
-: 1275:
-: 1276:/* See the description above for the fields in this structure */
-: 1277:typedef struct MPIR_Err_msg
-: 1278:{
-: 1279: int id;
-: 1280: int prev_error;
-: 1281: int use_user_error_code;
-: 1282: int user_error_code;
-: 1283:
-: 1284: char location[MAX_LOCATION_LEN+1];
-: 1285: char msg[MPIR_MAX_ERROR_LINE+1];
-: 1286:}
-: 1287:MPIR_Err_msg_t;
-: 1288:
-: 1289:static MPIR_Err_msg_t ErrorRing[MAX_ERROR_RING];
-: 1290:static volatile unsigned int error_ring_loc = 0;
-: 1291:static volatile unsigned int max_error_ring_loc = 0;
-: 1292:
-: 1293:/* FIXME: This needs to be made consistent with the different thread levels,
-: 1294: since in the "global" thread level, an extra thread mutex is not required. */
-: 1295:#if defined(MPID_REQUIRES_THREAD_SAFETY)
-: 1296:/* if the device requires internal MPICH routines to be thread safe, the
-: 1297: MPIU_THREAD_CHECK macros are not appropriate */
-: 1298:static MPID_Thread_mutex_t error_ring_mutex;
-: 1299:#define error_ring_mutex_create(_mpi_errno_p_) \
-: 1300: MPID_Thread_mutex_create(&error_ring_mutex, _mpi_errno_p_)
-: 1301:#define error_ring_mutex_destroy(_mpi_errno_p) \
-: 1302: MPID_Thread_mutex_destroy(&error_ring_mutex, _mpi_errno_p_)
-: 1303:#define error_ring_mutex_lock() \
-: 1304: MPID_Thread_mutex_lock(&error_ring_mutex)
-: 1305:#define error_ring_mutex_unlock() \
-: 1306: MPID_Thread_mutex_unlock(&error_ring_mutex)
-: 1307:#elif defined(MPICH_IS_THREADED)
-: 1308:static MPID_Thread_mutex_t error_ring_mutex;
-: 1309:#define error_ring_mutex_create(_mpi_errno_p) MPID_Thread_mutex_create(&error_ring_mutex,_mpi_errno_p)
-: 1310:#define error_ring_mutex_destroy(_mpi_errno_p) MPID_Thread_mutex_destroy(&error_ring_mutex,_mpi_errno_p)
-: 1311:#define error_ring_mutex_lock() \
-: 1312: MPIU_THREAD_CHECK_BEGIN \
-: 1313: MPID_Thread_mutex_lock(&error_ring_mutex) \
-: 1314: MPIU_THREAD_CHECK_END
-: 1315:#define error_ring_mutex_unlock() \
-: 1316: MPIU_THREAD_CHECK_BEGIN \
-: 1317: MPID_Thread_mutex_unlock(&error_ring_mutex) \
-: 1318: MPIU_THREAD_CHECK_END
-: 1319:#else
-: 1320:#define error_ring_mutex_create(_a)
-: 1321:#define error_ring_mutex_destroy(_a)
-: 1322:#define error_ring_mutex_lock()
-: 1323:#define error_ring_mutex_unlock()
-: 1324:#endif
-: 1325:
-: 1326:/* Create the ring id from information about the message */
-: 1327:static void ErrcodeCreateID( int error_class, int generic_idx,
-: 1328: const char *msg, int *id, int *seq )
10053: 1329:{
-: 1330: int i;
10053: 1331: int ring_seq = 0, ring_id;
-: 1332:
-: 1333: /* Create a simple hash function of the message to serve as the
-: 1334: sequence number */
10053: 1335: ring_seq = 0;
749788: 1336: for (i=0; msg[i]; i++)
739735: 1337: ring_seq += (unsigned int) msg[i];
-: 1338:
10053: 1339: ring_seq %= ERROR_SPECIFIC_SEQ_SIZE;
-: 1340:
10053: 1341: ring_id = (error_class & ERROR_CLASS_MASK) |
-: 1342: ((generic_idx + 1) << ERROR_GENERIC_SHIFT) |
-: 1343: (ring_seq << ERROR_SPECIFIC_SEQ_SHIFT);
-: 1344:
10053: 1345: *id = ring_id;
10053: 1346: *seq = ring_seq;
10053: 1347:}
-: 1348:
-: 1349:/* Convert an error code into ring_idx, ring_id, and generic_idx.
-: 1350: Return non-zero if there is a problem with the decode values
-: 1351: (e.g., out of range for the ring index) */
-: 1352:static int convertErrcodeToIndexes( int errcode, int *ring_idx, int *ring_id,
-: 1353: int *generic_idx )
15136: 1354:{
15136: 1355: *ring_idx = (errcode & ERROR_SPECIFIC_INDEX_MASK) >>
-: 1356: ERROR_SPECIFIC_INDEX_SHIFT;
15136: 1357: *ring_id = errcode & (ERROR_CLASS_MASK |
-: 1358: ERROR_GENERIC_MASK | ERROR_SPECIFIC_SEQ_MASK);
15136: 1359: *generic_idx = ((errcode & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT) - 1;
-: 1360:
-: 1361: /* Test on both the max_error_ring_loc and MAX_ERROR_RING to guard
-: 1362: against memory overwrites */
15136: 1363: if (*ring_idx < 0 || *ring_idx >= MAX_ERROR_RING ||
|
#####: 1364: *ring_idx > max_error_ring_loc) return 1;
-: 1365:
|
15136: 1366: return 0;
-: 1367:}
-: 1368:static int checkErrcodeIsValid( int errcode )
2072: 1369:{
-: 1370: int ring_id, generic_idx, ring_idx;
-: 1371:
-: 1372: /* If the errcode is a class, then it is valid */
2072: 1373: if (errcode <= MPIR_MAX_ERROR_CLASS_INDEX && errcode >= 0) return 0;
-: 1374:
2068: 1375: convertErrcodeToIndexes( errcode, &ring_idx, &ring_id, &generic_idx );
2068: 1376: if (ring_idx < 0 || ring_idx >= MAX_ERROR_RING ||
|
#####: 1377: ring_idx > max_error_ring_loc) return 1;
|
2068: 1378: if (ErrorRing[ring_idx].id != ring_id) return 2;
-: 1379: /* It looks like the code uses a generic idx of -1 to indicate no
-: 1380: generic message */
2068: 1381: if (generic_idx < -1 || generic_idx > generic_msgs_len) return 3;
2068: 1382: return 0;
-: 1383:}
-: 1384:static const char *ErrcodeInvalidReasonStr( int reason )
|
#####: 1385:{
#####: 1386: const char *str = 0;
#####: 1387: switch (reason) {
-: 1388: case 1:
#####: 1389: str = "Ring Index out of range";
#####: 1390: break;
-: 1391: case 2:
#####: 1392: str = "Ring ids do not match";
#####: 1393: break;
-: 1394: case 3:
#####: 1395: str = "Generic message index out of range";
#####: 1396: break;
-: 1397: default:
#####: 1398: str = "Unknown reason for invalid errcode";
-: 1399: break;
-: 1400: }
#####: 1401: return str;
-: 1402:}
-: 1403:/* Check to see if the error code is a user-specified error code
-: 1404: (e.g., from the attribute delete function) and if so, set the error code
-: 1405: to the value provide by the user */
-: 1406:static int checkForUserErrcode( int errcode )
|
6938: 1407:{
6938: 1408: error_ring_mutex_lock();
-: 1409: {
6938: 1410: if (errcode != MPI_SUCCESS) {
-: 1411: int ring_idx;
-: 1412: int ring_id;
-: 1413: int generic_idx;
-: 1414:
6938: 1415: if (convertErrcodeToIndexes( errcode, &ring_idx, &ring_id,
-: 1416: &generic_idx ) != 0) {
|
#####: 1417: MPIU_Error_printf(
-: 1418: "Invalid error code (%d) (error ring index %d invalid)\n",
-: 1419: errcode, ring_idx );
-: 1420: }
-: 1421: else {
-: 1422: /* Can we get a more specific error message */
|
6938: 1423: if (generic_idx >= 0 &&
-: 1424: ErrorRing[ring_idx].id == ring_id &&
-: 1425: ErrorRing[ring_idx].use_user_error_code)
-: 1426: {
25: 1427: errcode = ErrorRing[ring_idx].user_error_code;
-: 1428: }
-: 1429: }
-: 1430: }
-: 1431: }
6938: 1432: error_ring_mutex_unlock();
6938: 1433: return errcode;
-: 1434:}
-: 1435:
-: 1436:/*
-: 1437: * This is the real routine for generating an error code. It takes
-: 1438: * a va_list so that it can be called by any routine that accepts a
-: 1439: * variable number of arguments.
-: 1440: */
|
-: 1441:int MPIR_Err_create_code_valist( int lastcode, int fatal, const char fcname[],
-: 1442: int line, int error_class,
-: 1443: const char generic_msg[],
-: 1444: const char specific_msg[], va_list Argp )
|
10055: 1445:{
-: 1446: int err_code;
-: 1447: int generic_idx;
10055: 1448: int use_user_error_code = 0;
10055: 1449: int user_error_code = -1;
-: 1450: char user_ring_msg[MPIR_MAX_ERROR_LINE+1];
-: 1451:
-: 1452: /* Create the code from the class and the message ring index */
-: 1453:
-: 1454: /* Check that lastcode is valid */
10055: 1455: if (lastcode != MPI_SUCCESS) {
-: 1456: int reason;
2072: 1457: reason = checkErrcodeIsValid(lastcode);
2072: 1458: if (reason) {
|
#####: 1459: MPIU_Error_printf( "Internal Error: invalid error code %x (%s) in %s:%d\n",
-: 1460: lastcode, ErrcodeInvalidReasonStr( reason ),
-: 1461: fcname, line );
#####: 1462: lastcode = MPI_SUCCESS;
-: 1463: }
-: 1464: }
-: 1465:
-: 1466: /* FIXME: ERR_OTHER is overloaded; this may mean "OTHER" or it may
-: 1467: mean "No additional error, just routine stack info" */
|
10055: 1468: if (error_class == MPI_ERR_OTHER)
-: 1469: {
2163: 1470: if (MPIR_ERR_GET_CLASS(lastcode) > MPI_SUCCESS &&
-: 1471: MPIR_ERR_GET_CLASS(lastcode) <= MPICH_ERR_LAST_CLASS)
-: 1472: {
-: 1473: /* If the last class is more specific (and is valid), then pass it
-: 1474: through */
2067: 1475: error_class = MPIR_ERR_GET_CLASS(lastcode);
-: 1476: }
-: 1477: else
-: 1478: {
96: 1479: error_class = MPI_ERR_OTHER;
-: 1480: }
-: 1481: }
-: 1482:
-: 1483: /* Handle special case of MPI_ERR_IN_STATUS. According to the standard,
-: 1484: the code must be equal to the class. See section 3.7.5.
-: 1485: Information on the particular error is in the MPI_ERROR field
-: 1486: of the status. */
10055: 1487: if (error_class == MPI_ERR_IN_STATUS)
-: 1488: {
2: 1489: return MPI_ERR_IN_STATUS;
-: 1490: }
-: 1491:
10053: 1492: err_code = error_class;
-: 1493:
-: 1494: /* Handle the generic message. This selects a subclass, based on a text
-: 1495: string */
-: 1496:# if MPICH_ERROR_MSG_LEVEL >= MPICH_ERROR_MSG_GENERIC
-: 1497: {
10053: 1498: generic_idx = FindGenericMsgIndex(generic_msg);
10053: 1499: if (generic_idx >= 0) {
10053: 1500: if (strcmp( generic_err_msgs[generic_idx].short_name, "**user" ) == 0)
-: 1501: {
25: 1502: use_user_error_code = 1;
-: 1503: /* This is a special case. The format is
-: 1504: "**user", "**userxxx %d", intval
-: 1505: (generic, specific, parameter). In this
-: 1506: case we must ... save the user value because
-: 1507: we store it explicitly in the ring.
-: 1508: We do this here because we cannot both access the
-: 1509: user error code and pass the argp to vsnprintf_mpi . */
25: 1510: if (specific_msg) {
-: 1511: const char *specific_fmt;
-: 1512: int specific_idx;
25: 1513: user_error_code = va_arg(Argp,int);
-: 1514:#if MPICH_ERROR_MSG_LEVEL > MPICH_ERROR_MSG_GENERIC
25: 1515: specific_idx = FindSpecificMsgIndex(specific_msg);
25: 1516: if (specific_idx >= 0) {
25: 1517: specific_fmt = specific_err_msgs[specific_idx].long_name;
-: 1518: }
-: 1519: else {
|
#####: 1520: specific_fmt = specific_msg;
-: 1521: }
-: 1522:#else
-: 1523: specific_fmt = specific_msg;
-: 1524:#endif
|
25: 1525: MPIU_Snprintf( user_ring_msg, sizeof(user_ring_msg),
-: 1526: specific_fmt, user_error_code );
-: 1527: }
-: 1528: else {
|
#####: 1529: user_ring_msg[0] = 0;
-: 1530: }
-: 1531: }
|
10053: 1532: err_code |= (generic_idx + 1) << ERROR_GENERIC_SHIFT;
-: 1533: }
-: 1534: else
-: 1535: {
-: 1536: /* TODO: lookup index for class error message */
|
#####: 1537: err_code &= ~ERROR_GENERIC_MASK;
-: 1538:
-: 1539:# ifdef MPICH_DBG_OUTPUT
-: 1540: {
-: 1541: if (generic_msg[0] == '*' && generic_msg[1] == '*')
-: 1542: {
-: 1543: /* FIXME : Internal error. Generate some debugging
-: 1544: information; Fix for the general release */
-: 1545: fprintf( stderr, "Could not find %s in list of messages\n", generic_msg );
-: 1546: }
-: 1547: }
-: 1548:# endif
-: 1549: }
-: 1550: }
-: 1551:# endif
-: 1552:
-: 1553: /* Handle the instance-specific part of the error message */
-: 1554:# if MPICH_ERROR_MSG_LEVEL == MPICH_ERROR_MSG_ALL
-: 1555: {
-: 1556: int specific_idx;
|
10053: 1557: const char * specific_fmt = 0;
10053: 1558: int ring_idx, ring_seq=0;
-: 1559: char * ring_msg;
-: 1560:
10053: 1561: error_ring_mutex_lock();
-: 1562: {
-: 1563: /* Get the next entry in the ring; keep track of what part of the
-: 1564: ring is in use (max_error_ring_loc) */
10053: 1565: ring_idx = error_ring_loc++;
10053: 1566: if (error_ring_loc >= MAX_ERROR_RING)
48: 1567: error_ring_loc %= MAX_ERROR_RING;
10053: 1568: if (error_ring_loc > max_error_ring_loc)
4243: 1569: max_error_ring_loc = error_ring_loc;
-: 1570:
10053: 1571: ring_msg = ErrorRing[ring_idx].msg;
-: 1572:
10053: 1573: if (specific_msg != NULL)
-: 1574: {
9486: 1575: specific_idx = FindSpecificMsgIndex(specific_msg);
9486: 1576: if (specific_idx >= 0)
-: 1577: {
9486: 1578: specific_fmt = specific_err_msgs[specific_idx].long_name;
-: 1579: }
-: 1580: else
-: 1581: {
|
#####: 1582: specific_fmt = specific_msg;
-: 1583: }
-: 1584: /* See the code above for handling user errors */
|
9486: 1585: if (!use_user_error_code) {
9461: 1586: vsnprintf_mpi( ring_msg, MPIR_MAX_ERROR_LINE,
-: 1587: specific_fmt, Argp );
-: 1588: }
-: 1589: else {
25: 1590: MPIU_Strncpy( ring_msg, user_ring_msg, MPIR_MAX_ERROR_LINE );
-: 1591: }
-: 1592: }
567: 1593: else if (generic_idx >= 0)
-: 1594: {
567: 1595: MPIU_Strncpy( ring_msg,generic_err_msgs[generic_idx].long_name,
-: 1596: MPIR_MAX_ERROR_LINE );
-: 1597: }
-: 1598: else
-: 1599: {
|
#####: 1600: MPIU_Strncpy( ring_msg, generic_msg, MPIR_MAX_ERROR_LINE );
-: 1601: }
-: 1602:
|
10053: 1603: ring_msg[MPIR_MAX_ERROR_LINE] = '\0';
-: 1604:
-: 1605: /* Get the ring sequence number and set the ring id */
10053: 1606: ErrcodeCreateID( error_class, generic_idx, ring_msg,
-: 1607: &ErrorRing[ring_idx].id, &ring_seq );
-: 1608: /* Set the previous code. */
10053: 1609: ErrorRing[ring_idx].prev_error = lastcode;
-: 1610:
-: 1611: /* */
10053: 1612: if (use_user_error_code)
-: 1613: {
25: 1614: ErrorRing[ring_idx].use_user_error_code = 1;
25: 1615: ErrorRing[ring_idx].user_error_code = user_error_code;
-: 1616: }
10028: 1617: else if (lastcode != MPI_SUCCESS)
-: 1618: {
-: 1619: int last_ring_idx;
-: 1620: int last_ring_id;
-: 1621: int last_generic_idx;
-: 1622:
2070: 1623: if (convertErrcodeToIndexes( lastcode, &last_ring_idx,
-: 1624: &last_ring_id,
-: 1625: &last_generic_idx ) != 0) {
|
#####: 1626: MPIU_Error_printf(
-: 1627: "Invalid error code (%d) (error ring index %d invalid)\n",
-: 1628: lastcode, last_ring_idx );
-: 1629: }
-: 1630: else {
|
2070: 1631: if (last_generic_idx >= 0 &&
-: 1632: ErrorRing[last_ring_idx].id == last_ring_id) {
2068: 1633: if (ErrorRing[last_ring_idx].use_user_error_code) {
36: 1634: ErrorRing[ring_idx].use_user_error_code = 1;
36: 1635: ErrorRing[ring_idx].user_error_code =
-: 1636: ErrorRing[last_ring_idx].user_error_code;
-: 1637: }
-: 1638: }
-: 1639: }
-: 1640: }
-: 1641:
10053: 1642: if (fcname != NULL)
-: 1643: {
10053: 1644: MPIU_Snprintf(ErrorRing[ring_idx].location, MAX_LOCATION_LEN, "%s(%d)", fcname, line);
10053: 1645: ErrorRing[ring_idx].location[MAX_LOCATION_LEN] = '\0';
-: 1646: }
-: 1647: else
-: 1648: {
|
#####: 1649: ErrorRing[ring_idx].location[0] = '\0';
-: 1650: }
-: 1651: }
|
10053: 1652: error_ring_mutex_unlock();
-: 1653:
10053: 1654: err_code |= ring_idx << ERROR_SPECIFIC_INDEX_SHIFT;
10053: 1655: err_code |= ring_seq << ERROR_SPECIFIC_SEQ_SHIFT;
-: 1656:
-: 1657: }
-: 1658:# endif
-: 1659:
10053: 1660: if (fatal || MPIR_Err_is_fatal(lastcode))
-: 1661: {
6: 1662: err_code |= ERROR_FATAL_MASK;
-: 1663: }
-: 1664:
10053: 1665: return err_code;
-: 1666:}
-: 1667:
-: 1668:/* Append an error code, error2, to the end of a list of messages in the error
-: 1669: ring whose head endcoded in error1_code. An error code pointing at the
-: 1670: combination is returned. If the list of messages does not terminate cleanly
-: 1671: (i.e. ring wrap has occurred), then the append is not performed. and error1
-: 1672: is returned (although it may include the class of error2 if the class of
-: 1673: error1 was MPI_ERR_OTHER). */
-: 1674:int MPIR_Err_combine_codes(int error1, int error2)
|
#####: 1675:{
#####: 1676: int error1_code = error1;
#####: 1677: int error2_code = error2;
-: 1678: int error2_class;
-: 1679:
#####: 1680: if (error2_code == MPI_SUCCESS) return error1_code;
#####: 1681: if (error2_code & ERROR_DYN_MASK) return error2_code;
#####: 1682: if (error1_code == MPI_SUCCESS) return error2_code;
-: 1683:
#####: 1684: error2_class = MPIR_ERR_GET_CLASS(error2_code);
#####: 1685: if (MPIR_ERR_GET_CLASS(error2_class) < MPI_SUCCESS ||
-: 1686: MPIR_ERR_GET_CLASS(error2_class) > MPICH_ERR_LAST_CLASS)
-: 1687: {
#####: 1688: error2_class = MPI_ERR_OTHER;
-: 1689: }
-: 1690:
-: 1691:# if MPICH_ERROR_MSG_LEVEL >= MPICH_ERROR_MSG_ALL
-: 1692: {
-: 1693: int error_code;
-: 1694:
#####: 1695: error_code = error1_code;
-: 1696:
#####: 1697: error_ring_mutex_lock();
-: 1698: {
-: 1699: for (;;)
-: 1700: {
-: 1701: int error_class;
-: 1702: int ring_idx;
-: 1703: int ring_id;
-: 1704: int generic_idx;
-: 1705:
#####: 1706: if (convertErrcodeToIndexes(error_code, &ring_idx, &ring_id,
-: 1707: &generic_idx) != 0 || generic_idx < 0 ||
-: 1708: ErrorRing[ring_idx].id != ring_id)
-: 1709: {
-: 1710: break;
-: 1711: }
-: 1712:
#####: 1713: error_code = ErrorRing[ring_idx].prev_error;
-: 1714:
#####: 1715: if (error_code == MPI_SUCCESS)
-: 1716: {
#####: 1717: ErrorRing[ring_idx].prev_error = error2;
#####: 1718: break;
-: 1719: }
-: 1720:
#####: 1721: error_class = MPIR_ERR_GET_CLASS(error_code);
-: 1722:
#####: 1723: if (error_class == MPI_ERR_OTHER)
-: 1724: {
#####: 1725: ErrorRing[ring_idx].prev_error &= ~(ERROR_CLASS_MASK);
#####: 1726: ErrorRing[ring_idx].prev_error |= error2_class;
-: 1727: }
-: 1728: }
-: 1729: }
#####: 1730: error_ring_mutex_unlock();
-: 1731: }
-: 1732:# endif
-: 1733:
#####: 1734: if (MPIR_ERR_GET_CLASS(error1_code) == MPI_ERR_OTHER)
-: 1735: {
#####: 1736: error1_code = (error1_code & ~(ERROR_CLASS_MASK)) | error2_class;
-: 1737: }
-: 1738:
#####: 1739: return error1_code;
-: 1740:}
-: 1741:
-: 1742:
-: 1743:/* ------------------------------------------------------------------------- */
-: 1744:/* Manage the error reporting stack */
-: 1745:/* ------------------------------------------------------------------------- */
-: 1746:/* FIXME: This flag wasn't documented in the release specs, and in any
-: 1747: event shouldn't be controlled through source-code changes (i.e.,
-: 1748: make it either a configure option or a runtime option) */
-: 1749:/* turn this flag on until we debug and release mpich2 */
-: 1750:static int MPIR_Err_print_stack_flag = TRUE;
-: 1751:static int MPIR_Err_chop_error_stack = FALSE;
-: 1752:static int MPIR_Err_chop_width = 80;
-: 1753:
-: 1754:static void MPIR_Err_stack_init( void )
|
4383: 1755:{
4383: 1756: int n, rc, mpi_errno = MPI_SUCCESS;
-: 1757:
4383: 1758: error_ring_mutex_create(&mpi_errno);
4383: 1759: MPIR_Err_chop_error_stack = FALSE;
-: 1760:
4383: 1761: rc = MPIU_GetEnvBool( "MPICH_PRINT_ERROR_STACK",
-: 1762: &MPIR_Err_print_stack_flag );
-: 1763:
4383: 1764: rc = MPIU_GetEnvInt( "MPICH_CHOP_ERROR_STACK", &n );
4383: 1765: if (rc == 1) {
-: 1766:#ifdef HAVE_WINDOWS_H
-: 1767: /* If windows, set the default width to the window size */
-: 1768: HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
-: 1769: if (hConsole != INVALID_HANDLE_VALUE)
-: 1770: {
-: 1771: CONSOLE_SCREEN_BUFFER_INFO info;
-: 1772: if (GetConsoleScreenBufferInfo(hConsole, &info))
-: 1773: {
-: 1774: MPIR_Err_chop_width = info.dwMaximumWindowSize.X;
-: 1775: }
-: 1776: }
-: 1777:#endif
|
#####: 1778: if (n > 0) {
#####: 1779: MPIR_Err_chop_error_stack = TRUE;
#####: 1780: MPIR_Err_chop_width = n;
-: 1781: }
#####: 1782: else if (n == 0) {
-: 1783: /* Use the default width */
#####: 1784: MPIR_Err_chop_error_stack = TRUE;
-: 1785: }
-: 1786: }
|
4383: 1787:}
-: 1788:
-: 1789:/**/
-: 1790:/* Given an error code, print the stack of messages corresponding to this
-: 1791: error code. */
-: 1792:void MPIR_Err_print_stack(FILE * fp, int errcode)
|
#####: 1793:{
#####: 1794: error_ring_mutex_lock();
-: 1795: {
#####: 1796: while (errcode != MPI_SUCCESS) {
-: 1797: int ring_idx;
-: 1798: int ring_id;
-: 1799: int generic_idx;
-: 1800:
#####: 1801: if (convertErrcodeToIndexes( errcode, &ring_idx, &ring_id,
-: 1802: &generic_idx ) != 0) {
#####: 1803: MPIU_Error_printf(
-: 1804: "Invalid error code (%d) (error ring index %d invalid)\n",
-: 1805: errcode, ring_idx );
#####: 1806: break;
-: 1807: }
-: 1808:
#####: 1809: if (generic_idx < 0)
-: 1810: {
#####: 1811: break;
-: 1812: }
-: 1813:
#####: 1814: if (ErrorRing[ring_idx].id == ring_id)
-: 1815: {
#####: 1816: fprintf(fp, "%s: %s\n", ErrorRing[ring_idx].location,
-: 1817: ErrorRing[ring_idx].msg);
#####: 1818: errcode = ErrorRing[ring_idx].prev_error;
-: 1819: }
-: 1820: else
-: 1821: {
#####: 1822: break;
-: 1823: }
-: 1824: }
-: 1825: }
#####: 1826: error_ring_mutex_unlock();
-: 1827:
-: 1828: /* FIXME: This is wrong. The only way that you can get here without
-: 1829: errcode beign MPI_SUCCESS is if there is an error in the
-: 1830: processing of the error codes. Dropping through into the next
-: 1831: level of code (particularly when that code doesn't check for
-: 1832: valid error codes!) is erroneous */
#####: 1833: if (errcode == MPI_SUCCESS)
-: 1834: {
#####: 1835: goto fn_exit;
-: 1836: }
-: 1837:
-: 1838: {
-: 1839: int generic_idx;
-: 1840:
#####: 1841: generic_idx = ((errcode & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT) - 1;
-: 1842:
#####: 1843: if (generic_idx >= 0)
-: 1844: {
#####: 1845: fprintf(fp, "(unknown)(): %s\n", generic_err_msgs[generic_idx].long_name);
#####: 1846: goto fn_exit;
-: 1847: }
-: 1848: }
-: 1849:
-: 1850: {
-: 1851: int error_class;
-: 1852:
#####: 1853: error_class = ERROR_GET_CLASS(errcode);
-: 1854:
#####: 1855: if (error_class <= MPICH_ERR_LAST_CLASS)
-: 1856: {
#####: 1857: fprintf(fp, "(unknown)(): %s\n", get_class_msg(ERROR_GET_CLASS(errcode)));
-: 1858: }
-: 1859: else
-: 1860: {
-: 1861: /* FIXME: Not internationalized */
#####: 1862: fprintf(fp, "Error code contains an invalid class (%d)\n", error_class);
-: 1863: }
-: 1864: }
-: 1865:
-: 1866: fn_exit:
-: 1867: return;
-: 1868:}
-: 1869:
-: 1870:/* FIXME: Shouldn't str be const char * ? */
-: 1871:static void MPIR_Err_print_stack_string(int errcode, char *str, int maxlen )
|
1035: 1872:{
1035: 1873: char *str_orig = str;
-: 1874: int len;
-: 1875:
1035: 1876: error_ring_mutex_lock();
-: 1877: {
-: 1878: /* Find the longest fcname in the stack */
1035: 1879: int max_location_len = 0;
1035: 1880: int tmp_errcode = errcode;
4100: 1881: while (tmp_errcode != MPI_SUCCESS) {
-: 1882: int ring_idx;
-: 1883: int ring_id;
-: 1884: int generic_idx;
-: 1885:
2030: 1886: if (convertErrcodeToIndexes( tmp_errcode, &ring_idx, &ring_id,
-: 1887: &generic_idx ) != 0) {
|
#####: 1888: MPIU_Error_printf(
-: 1889: "Invalid error code (%d) (error ring index %d invalid)\n",
-: 1890: errcode, ring_idx );
#####: 1891: break;
-: 1892: }
-: 1893:
|
2030: 1894: if (generic_idx < 0) {
|
#####: 1895: break;
-: 1896: }
-: 1897:
|
2030: 1898: if (ErrorRing[ring_idx].id == ring_id) {
2030: 1899: len = (int)strlen(ErrorRing[ring_idx].location);
2030: 1900: max_location_len = MPIR_MAX(max_location_len, len);
2030: 1901: tmp_errcode = ErrorRing[ring_idx].prev_error;
-: 1902: }
-: 1903: else
-: 1904: {
|
#####: 1905: break;
-: 1906: }
-: 1907: }
|
1035: 1908: max_location_len += 2; /* add space for the ": " */
-: 1909: /* print the error stack */
4100: 1910: while (errcode != MPI_SUCCESS) {
-: 1911: int ring_idx;
-: 1912: int ring_id;
-: 1913: int generic_idx;
-: 1914: int i;
-: 1915: char *cur_pos;
-: 1916:
2030: 1917: if (convertErrcodeToIndexes( errcode, &ring_idx, &ring_id,
-: 1918: &generic_idx ) != 0) {
|
#####: 1919: MPIU_Error_printf(
-: 1920: "Invalid error code (%d) (error ring index %d invalid)\n",
-: 1921: errcode, ring_idx );
-: 1922: }
-: 1923:
|
2030: 1924: if (generic_idx < 0)
-: 1925: {
|
#####: 1926: break;
-: 1927: }
-: 1928:
|
2030: 1929: if (ErrorRing[ring_idx].id == ring_id) {
-: 1930: int nchrs;
2030: 1931: MPIU_Snprintf(str, maxlen, "%s", ErrorRing[ring_idx].location);
2030: 1932: len = (int)strlen(str);
2030: 1933: maxlen -= len;
2030: 1934: str += len;
2030: 1935: nchrs = max_location_len -
-: 1936: (int)strlen(ErrorRing[ring_idx].location) - 2;
5921: 1937: while (nchrs > 0 && maxlen > 0) {
1861: 1938: *str++ = '.';
1861: 1939: nchrs--;
1861: 1940: maxlen--;
-: 1941: }
2030: 1942: if (maxlen > 0) {
2030: 1943: *str++ = ':';
2030: 1944: maxlen--;
-: 1945: }
2030: 1946: if (maxlen > 0) {
2030: 1947: *str++ = ' ';
2030: 1948: maxlen--;
-: 1949: }
-: 1950:
2030: 1951: if (MPIR_Err_chop_error_stack)
-: 1952: {
|
#####: 1953: cur_pos = ErrorRing[ring_idx].msg;
#####: 1954: len = (int)strlen(cur_pos);
#####: 1955: if (len == 0 && maxlen > 0) {
#####: 1956: *str++ = '\n';
#####: 1957: maxlen--;
-: 1958: }
#####: 1959: while (len)
-: 1960: {
#####: 1961: if (len >= MPIR_Err_chop_width - max_location_len)
-: 1962: {
#####: 1963: if (len > maxlen)
#####: 1964: break;
-: 1965: /* FIXME: Don't use Snprint to append a string ! */
#####: 1966: MPIU_Snprintf(str, MPIR_Err_chop_width - 1 - max_location_len, "%s", cur_pos);
#####: 1967: str[MPIR_Err_chop_width - 1 - max_location_len] = '\n';
#####: 1968: cur_pos += MPIR_Err_chop_width - 1 - max_location_len;
#####: 1969: str += MPIR_Err_chop_width - max_location_len;
#####: 1970: maxlen -= MPIR_Err_chop_width - max_location_len;
#####: 1971: if (maxlen < max_location_len)
#####: 1972: break;
#####: 1973: for (i=0; i<max_location_len; i++)
-: 1974: {
#####: 1975: MPIU_Snprintf(str, maxlen, " ");
#####: 1976: maxlen--;
#####: 1977: str++;
-: 1978: }
#####: 1979: len = (int)strlen(cur_pos);
-: 1980: }
-: 1981: else
-: 1982: {
#####: 1983: MPIU_Snprintf(str, maxlen, "%s\n", cur_pos);
#####: 1984: len = (int)strlen(str);
#####: 1985: maxlen -= len;
#####: 1986: str += len;
#####: 1987: len = 0;
-: 1988: }
-: 1989: }
-: 1990: }
-: 1991: else
-: 1992: {
|
2030: 1993: MPIU_Snprintf(str, maxlen, "%s\n", ErrorRing[ring_idx].msg);
2030: 1994: len = (int)strlen(str);
2030: 1995: maxlen -= len;
2030: 1996: str += len;
-: 1997: }
2030: 1998: errcode = ErrorRing[ring_idx].prev_error;
-: 1999: }
-: 2000: else
-: 2001: {
|
#####: 2002: break;
-: 2003: }
-: 2004: }
-: 2005: }
|
1035: 2006: error_ring_mutex_unlock();
-: 2007:
1035: 2008: if (errcode == MPI_SUCCESS)
-: 2009: {
1035: 2010: goto fn_exit;
-: 2011: }
-: 2012:
-: 2013: /* FIXME: The following code is broken as described above (if the errcode
-: 2014: is not valid, then this code is just going to cause more problems) */
-: 2015: {
-: 2016: int generic_idx;
-: 2017:
|
#####: 2018: generic_idx = ((errcode & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT) - 1;
-: 2019:
#####: 2020: if (generic_idx >= 0)
-: 2021: {
-: 2022: const char *p;
-: 2023: /* FIXME: (Here and elsewhere) Make sure any string is
-: 2024: non-null before you use it */
#####: 2025: p = generic_err_msgs[generic_idx].long_name;
#####: 2026: if (!p) { p = "<NULL>"; }
#####: 2027: MPIU_Snprintf(str, maxlen, "(unknown)(): %s\n", p );
#####: 2028: len = (int)strlen(str);
#####: 2029: maxlen -= len;
#####: 2030: str += len;
#####: 2031: goto fn_exit;
-: 2032: }
-: 2033: }
-: 2034:
-: 2035: {
-: 2036: int error_class;
-: 2037:
#####: 2038: error_class = ERROR_GET_CLASS(errcode);
-: 2039:
#####: 2040: if (error_class <= MPICH_ERR_LAST_CLASS)
-: 2041: {
#####: 2042: MPIU_Snprintf(str, maxlen, "(unknown)(): %s\n",
-: 2043: get_class_msg(ERROR_GET_CLASS(errcode)));
#####: 2044: len = (int)strlen(str);
#####: 2045: maxlen -= len;
#####: 2046: str += len;
-: 2047: }
-: 2048: else
-: 2049: {
-: 2050: /* FIXME: Not internationalized */
#####: 2051: MPIU_Snprintf(str, maxlen,
-: 2052: "Error code contains an invalid class (%d)\n",
-: 2053: error_class);
#####: 2054: len = (int)strlen(str);
#####: 2055: maxlen -= len;
#####: 2056: str += len;
-: 2057: }
-: 2058: }
-: 2059:
|
1035: 2060: fn_exit:
1035: 2061: if (str_orig != str)
-: 2062: {
1035: 2063: str--;
1035: 2064: *str = '\0';
-: 2065: }
-: 2066: return;
-: 2067:}
-: 2068:
-: 2069:/* FIXME: Remove the bogus fn argument from all uses of this routine */
-: 2070:static int ErrGetInstanceString( int errorcode, char *msg, int num_remaining,
-: 2071: MPIR_Err_get_class_string_func_t fn ATTRIBUTE((unused)) )
1035: 2072:{
-: 2073: int len;
-: 2074:
1035: 2075: if (MPIR_Err_print_stack_flag) {
1035: 2076: MPIU_Strncpy(msg, ", error stack:\n", num_remaining);
1035: 2077: msg[num_remaining - 1] = '\0';
1035: 2078: len = (int)strlen(msg);
1035: 2079: msg += len;
1035: 2080: num_remaining -= len;
-: 2081: /* note: this took the "fn" arg, but that appears to be unused
-: 2082: and is undocumented. */
1035: 2083: MPIR_Err_print_stack_string(errorcode, msg, num_remaining);
1035: 2084: msg[num_remaining - 1] = '\0';
-: 2085: }
-: 2086: else {
|
#####: 2087: error_ring_mutex_lock();
-: 2088: {
#####: 2089: while (errorcode != MPI_SUCCESS) {
-: 2090: int ring_idx;
-: 2091: int ring_id;
-: 2092: int generic_idx;
-: 2093:
#####: 2094: if (convertErrcodeToIndexes( errorcode, &ring_idx,
-: 2095: &ring_id,
-: 2096: &generic_idx ) != 0) {
#####: 2097: MPIU_Error_printf(
-: 2098: "Invalid error code (%d) (error ring index %d invalid)\n",
-: 2099: errorcode, ring_idx );
#####: 2100: break;
-: 2101: }
-: 2102:
#####: 2103: if (generic_idx < 0) {
#####: 2104: break;
-: 2105: }
-: 2106:
#####: 2107: if (ErrorRing[ring_idx].id == ring_id) {
-: 2108: /* just keep clobbering old values until the
-: 2109: end of the stack is reached */
#####: 2110: MPIU_Snprintf(msg, num_remaining, ", %s",
-: 2111: ErrorRing[ring_idx].msg);
#####: 2112: msg[num_remaining - 1] = '\0';
#####: 2113: errorcode = ErrorRing[ring_idx].prev_error;
-: 2114: }
-: 2115: else {
#####: 2116: break;
-: 2117: }
-: 2118: }
-: 2119: }
#####: 2120: error_ring_mutex_unlock();
-: 2121: }
-: 2122: /* FIXME: How do we determine that we failed to unwind the stack? */
|
1035: 2123: if (errorcode != MPI_SUCCESS) return 1;
-: 2124:
|
#####: 2125: return 0;
-: 2126:}
-: 2127:#endif
|