⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbg_printf.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. *//* * This file provides a set of routines that can be used to record debug * messages in a ring so that the may be dumped at a later time.  For example, * this can be used to record debug messages without printing them; when * a special event, such as an error occurs, a call to  * MPIU_dump_dbg_memlog( stderr ) will print the contents of the file ring * to stderr. */#include "mpiimpl.h"#include <stdio.h>#ifdef HAVE_STDARG_H#include <stdarg.h>#endif#ifdef HAVE_STRING_H#include <string.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif/* Temporary.  sig values will change *//* style: allow:vprintf:3 sig:0 *//* style: allow:fputs:1 sig:0 *//* style: allow:printf:2 sig:0 *//* style: allow:fprintf:7 sig:0 */#ifdef HAVE_VA_COPY# define va_copy_end(a) va_end(a)#else# ifdef HAVE___VA_COPY#  define va_copy(a,b) __va_copy(a,b)#  define va_copy_end(a) # else#  define va_copy(a,b) ((a) = (b))/* Some writers recommend define va_copy(a,b) memcpy(&a,&b,sizeof(va_list)) */#  define va_copy_end(a)# endif#endif#if !defined(MPICH_DBG_MEMLOG_NUM_LINES)#define MPICH_DBG_MEMLOG_NUM_LINES 1024#endif#if !defined(MPICH_DBG_MEMLOG_LINE_SIZE)#define MPICH_DBG_MEMLOG_LINE_SIZE 256#endifMPIU_dbg_state_t MPIUI_dbg_state = MPIU_DBG_STATE_UNINIT;FILE * MPIUI_dbg_fp = NULL;static int dbg_memlog_num_lines = MPICH_DBG_MEMLOG_NUM_LINES;static int dbg_memlog_line_size = MPICH_DBG_MEMLOG_LINE_SIZE;static char **dbg_memlog = NULL;static int dbg_memlog_next = 0;static int dbg_memlog_count = 0;static int dbg_rank = -1;static void dbg_init(void);int MPIU_dbg_init(int rank){    dbg_rank = rank;    if (MPIUI_dbg_state == MPIU_DBG_STATE_UNINIT)    {	dbg_init();    }    /* If file logging is enable, we need to open a file */    if (MPIUI_dbg_state & MPIU_DBG_STATE_FILE)    {	char fn[128];	/* Only open the file only once in case MPIU_dbg_init is called more 	   than once */	if (MPIUI_dbg_fp == NULL)	{	    MPIU_Snprintf(fn, 128, "mpich2-dbg-%d.log", dbg_rank);	    MPIUI_dbg_fp = fopen(fn, "w");	    setvbuf(MPIUI_dbg_fp, NULL, _IONBF, 0);	}    }        return 0;}static void dbg_init(void){    char * envstr;        MPIUI_dbg_state = MPIU_DBG_STATE_NONE;    /* FIXME: This should use MPIU_Param_get_string */    envstr = getenv("MPICH_DBG_OUTPUT");    if (envstr == NULL)    {	return;    }    /*     * TODO:     *     * - parse environment variable to determine number of log lines, etc.     *     * - add support for writing to a (per-process or global?) file     *     * - add support for sending to a log server, perhaps with global time     *   sequencing information ???     */    if (strstr(envstr, "stdout"))    {	MPIUI_dbg_state = (MPIU_dbg_state_t)( MPIU_DBG_STATE_STDOUT | 					      MPIUI_dbg_state );    }    if (strstr(envstr, "memlog"))    {	MPIUI_dbg_state = (MPIU_dbg_state_t)( MPIU_DBG_STATE_MEMLOG |					      MPIUI_dbg_state );    }    if (strstr(envstr, "file"))    {	MPIUI_dbg_state = (MPIU_dbg_state_t) ( MPIU_DBG_STATE_FILE |					       MPIUI_dbg_state );    }    /* If memlog is enabled, the we need to allocate some memory for it */    if (MPIUI_dbg_state & MPIU_DBG_STATE_MEMLOG)    {	dbg_memlog = MPIU_Malloc(dbg_memlog_num_lines * sizeof(char *) +				 dbg_memlog_num_lines * dbg_memlog_line_size);	if (dbg_memlog != NULL)	{	    int i;	    	    for (i = 0; i < dbg_memlog_num_lines ; i++)	    {		dbg_memlog[i] = ((char *) &dbg_memlog[dbg_memlog_num_lines]) + 		    i * dbg_memlog_line_size;	    }	}	else	{	    MPIUI_dbg_state = (MPIU_dbg_state_t)( MPIUI_dbg_state & 						  ~MPIU_DBG_STATE_MEMLOG );	}    }}int MPIU_dbglog_printf(const char *str, ...){    int n = 0;    va_list list;    if (MPIUI_dbg_state == MPIU_DBG_STATE_UNINIT)    {	dbg_init();    }    if (MPIUI_dbg_state & MPIU_DBG_STATE_MEMLOG)    {	/* FIXME: put everything on one line until a \n is found */		dbg_memlog[dbg_memlog_next][0] = '\0';	va_start(list, str);	n = vsnprintf(dbg_memlog[dbg_memlog_next], dbg_memlog_line_size, str, 		      list);	va_end(list);	/* if the output was truncated, we null terminate the end of the	   string, on the off chance that vsnprintf() didn't do that.  we also	   check to see if any data has been written over the null we set at	   the beginning of the string.  this is mostly paranoia, but the man	   page does not clearly state what happens when truncation occurs.  if	   data was written to the string, we would like to output it, but we	   want to avoid reading past the end of the array or outputing garbage	   data. */	if (n < 0 || n >= dbg_memlog_line_size)	{	    dbg_memlog[dbg_memlog_next][dbg_memlog_line_size - 1] = '\0';	    n = (int)strlen(dbg_memlog[dbg_memlog_next]);	}	if (dbg_memlog[dbg_memlog_next][0] != '\0')	{	    dbg_memlog_next = (dbg_memlog_next + 1) % dbg_memlog_num_lines;	    dbg_memlog_count++;	}    }    if (MPIUI_dbg_state & MPIU_DBG_STATE_STDOUT)    {	va_start(list, str);	n = vprintf(str, list);	va_end(list);    }    if ((MPIUI_dbg_state & MPIU_DBG_STATE_FILE) && MPIUI_dbg_fp != NULL)    {	va_start(list, str);	n = vfprintf(MPIUI_dbg_fp, str, list);	va_end(list);    }    return n;}int MPIU_dbglog_vprintf(const char *str, va_list ap){    int n = 0;    va_list list;    if (MPIUI_dbg_state == MPIU_DBG_STATE_UNINIT)    {	dbg_init();    }    if (MPIUI_dbg_state & MPIU_DBG_STATE_MEMLOG)    {	va_copy(list,ap);	dbg_memlog[dbg_memlog_next][0] = '\0';	n = vsnprintf(dbg_memlog[dbg_memlog_next], dbg_memlog_line_size, str, 		      list);        va_copy_end(list);	/* if the output was truncated, we null terminate the end of the	   string, on the off chance that vsnprintf() didn't do that.  we also	   check to see if any data has been written over the null we set at	   the beginning of the string.  this is mostly paranoia, but the man	   page does not clearly state what happens when truncation occurs.  if	   data was written to the string, we would like to output it, but we	   want to avoid reading past the end of the array or outputing garbage	   data. */	if (n < 0 || n >= dbg_memlog_line_size)	{	    dbg_memlog[dbg_memlog_next][dbg_memlog_line_size - 1] = '\0';	    n = (int)strlen(dbg_memlog[dbg_memlog_next]);	}	if (dbg_memlog[dbg_memlog_next][0] != '\0')	{	    dbg_memlog_next = (dbg_memlog_next + 1) % dbg_memlog_num_lines;	    dbg_memlog_count++;	}    }    if (MPIUI_dbg_state & MPIU_DBG_STATE_STDOUT)    {	va_copy(list, ap);	n = vprintf(str, list);	va_copy_end(list);    }    if ((MPIUI_dbg_state & MPIU_DBG_STATE_FILE) && MPIUI_dbg_fp != NULL)    {	va_copy(list, ap);	n = vfprintf(MPIUI_dbg_fp, str, list);	va_end(list);    }    return n;}/* FIXME: */int MPIU_dbg_printf(const char * str, ...){    int n;        /* MPID_Common_thread_lock(); */    {	va_list list;	MPIU_dbglog_printf("[%d]", dbg_rank);	va_start(list, str);	n = MPIU_dbglog_vprintf(str, list);	va_end(list);	MPIU_dbglog_flush();    }    /* MPID_Common_thread_unlock(); */        return n;}void MPIU_dump_dbg_memlog_to_stdout(void){    MPIU_dump_dbg_memlog(stdout);}void MPIU_dump_dbg_memlog_to_file(const char *filename){    FILE *fout;    fout = fopen(filename, "wb");    if (fout != NULL)    {	MPIU_dump_dbg_memlog(fout);	fclose(fout);    }}void MPIU_dump_dbg_memlog(FILE * fp){    if (dbg_memlog_count != 0)    {	int ent;	int last_ent;	/* there is a small issue with counter rollover which will need to be	   fixed if more than 2^32 lines are going to be logged */	ent = (dbg_memlog_next == dbg_memlog_count) ? 0 : dbg_memlog_next;	last_ent = (ent + dbg_memlog_num_lines - 1) % dbg_memlog_num_lines;		do	{	    fputs(dbg_memlog[ent], fp);	    ent = (ent + 1) % dbg_memlog_num_lines;	}	while(ent != last_ent);	fflush(fp);    }}#ifdef USE_DBG_LOGGING/*  * NEW ROUTINES FOR DEBUGGING */int MPIU_DBG_ActiveClasses = 0;int MPIU_DBG_MaxLevel      = MPIU_DBG_TYPICAL;static int mpiu_dbg_initialized = 0;  /* 0, 1 (preinit), or 2 (init) */static FILE *MPIU_DBG_fp = 0;static char *filePattern = "-stdout-"; /* "log%d.log"; *//*    We keep information on the state of the file.     The issue is that sometimes we want to generate DBG output before we   know the rank (and world) of the process.   Thus, we have two values: whether the file has been opened, and if so,   if it was opened before or after the rank was available; and how the   file should be handled if I/O is performed before the rank is available.   Another option that could be considered is to store values that would   otherwise be written before the rank is available for opening the file.   Currently, this is not used to avoid allocating the necessary space. */typedef enum { MPIU_DBG_CLOSED, MPIU_DBG_PRERANK, MPIU_DBG_OPEN } FileState_t;static FileState_t filestate = MPIU_DBG_CLOSED;typedef enum { MPIU_DBG_REOPEN, MPIU_DBG_IGNORE_PRERANK, MPIU_DBG_OPENONCE }    FileOpenMode_t;static FileOpenMode_t filemode = MPIU_DBG_REOPEN;static char *defaultFilePattern = "dbg@W%w-@%d@T-%t@.log";static int worldNum  = 0;static int worldRank = -1;static int whichRank = -1;             /* all ranks */static double timeOrigin = 0.0;static int MPIU_DBG_Usage( const char *, const char * );static int MPIU_DBG_OpenFile( void );static int setDBGClass( const char * );static int SetDBGLevel( const char *, const char *([]) );int MPIU_DBG_Outevent( const char *file, int line, int class, int kind, 		       const char *fmat, ... ){    va_list list;    char *str, stmp[MPIU_DBG_MAXLINE];    int  i;    void *p;    MPID_Time_t t;    double  curtime;    int threadID  = 0;    if (!mpiu_dbg_initialized) return 0;#ifdef MPICH_IS_THREADED    {	MPE_Thread_id_t tid;	MPE_Thread_self(&tid);	threadID = (int)tid;    }#endif    if (!MPIU_DBG_fp) {	MPIU_DBG_OpenFile();    }    MPID_Wtime( &t );    MPID_Wtime_todouble( &t, &curtime );    curtime = curtime - timeOrigin;    /* The kind values are used with the macros to simplify these cases */    switch (kind) {	case 0:	    fprintf( MPIU_DBG_fp, "%d\t%d\t%d\t%d\t%f\t%s\t%d\t%s\n",		     worldNum, worldRank, threadID, class, curtime, 		     file, line, fmat );	    break;	case 1:	    va_start(list,fmat);	    str = va_arg(list,char *);	    MPIU_Snprintf( stmp, sizeof(stmp), fmat, str );	    va_end(list);	    fprintf( MPIU_DBG_fp, "%d\t%d\t%d\t%d\t%f\t%s\t%d\t%s\n",		     worldNum, worldRank, threadID, class, curtime, 		     file, line, stmp );	    break;	case 2: 	    va_start(list,fmat);	    i = va_arg(list,int);	    MPIU_Snprintf( stmp, sizeof(stmp), fmat, i);	    va_end(list);	    fprintf( MPIU_DBG_fp, "%d\t%d\t%d\t%d\t%f\t%s\t%d\t%s\n",		     worldNum, worldRank, threadID, class, curtime, 		     file, line, stmp );	    break;	case 3: 	    va_start(list,fmat);	    p = va_arg(list,void *);	    MPIU_Snprintf( stmp, sizeof(stmp), fmat, p);	    va_end(list);	    fprintf( MPIU_DBG_fp, "%d\t%d\t%d\t%d\t%f\t%s\t%d\t%s\n",		     worldNum, worldRank, threadID, class, curtime, 		     file, line, stmp );	    break;        default:	    break;    }    fflush(MPIU_DBG_fp);    return 0;}/* These are used to simplify the handling of options.     To add a new name, add an MPIU_DBG_ClassName element to the array   MPIU_Classnames.  The "classbits" values are defined by MPIU_DBG_CLASS   in src/include/mpidbg.h  */typedef struct MPIU_DBG_ClassName {    int        classbits;    const char *UCName, *LCName; } MPIU_DBG_ClassName;static const MPIU_DBG_ClassName MPIU_Classnames[] = {    { MPIU_DBG_PT2PT,         "PT2PT",         "pt2pt" },    { MPIU_DBG_RMA,           "RMA",           "rma"   },    { MPIU_DBG_THREAD,        "THREAD",        "thread" },    { MPIU_DBG_PM,            "PM",            "pm" },    { MPIU_DBG_ROUTINE_ENTER, "ROUTINE_ENTER", "routine_enter" },    { MPIU_DBG_ROUTINE_EXIT,  "ROUTINE_EXIT",  "routine_exit" },    { MPIU_DBG_ROUTINE_ENTER |      MPIU_DBG_ROUTINE_EXIT,  "ROUTINE",       "routine" },    { MPIU_DBG_SYSCALL,       "SYSCALL",       "syscall" },    { MPIU_DBG_DATATYPE,      "DATATYPE",      "datatype" },    { MPIU_DBG_HANDLE,        "HANDLE",        "handle" },    { MPIU_DBG_COMM,          "COMM",          "comm" },    { MPIU_DBG_BSEND,         "BSEND",         "bsend" },

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -