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

📄 picl.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Old-style Picl trace file handling routines for Upshot   Ed Karrels   Argonne National Laboratory*/#define DEBUG 0#include <stdio.h>#include <ctype.h>#ifdef NEEDS_STDLIB_PROTOTYPES#include "protofix.h"#endif/* here's hoping that sys/stat.h is common */#ifdef __FreeBSD__#include <sys/types.h>#endif#include <sys/stat.h>#include "tcl.h"#include "events.h"#include "states.h"#include "msgs.h"#include "procs.h"#include "log.h"#include "picl.h"#define MAX_LINE_LEN 1024#define MAX_WORD_LEN 64   /* If the user defines a whole buch of different tasks, say 0 through      100, we dont want to create a different state for every one, just      do a 'mod' down to 5 unique task types. */#define PICL_MAX_TASK_NO 5typedef enum {  min_recordType=0,  trace_start,			/* 1 */  open,				/* 2 */  load,				/* 3 */  send,				/* 4 */  probe,			/* 5 */  recv,				/* 6 */  recv_blocking,		/* 7 */  recv_waking,			/* 8 */  message,			/* 9 */  sync,				/* 10 */  compstats,			/* 11 */  commstats,			/* 12 */  close,			/* 13 */  trace_level,			/* 14 */  trace_mark,			/* 15 */  trace_message,		/* 16 */  trace_stop,			/* 17 */  trace_flush,			/* 18 */  trace_exit,			/* 19 */  block_begin,			/* 20 */  block_end,			/* 21 */  trace_marks,			/* 22 */  max_recordType} recordTypeEnum;typedef enum {   min_blockType=-5,   global_op,   bcast1,   bcast0,   barrier,   max_blockType} blockTypeEnum;static char *recordTypeNames[] = {   "trace_start",   "open",   "load",   "send",   "probe",			/* why left out? */   "recv",   "recv_blocking",   "recv_waking",   "message",   "sync",   "compstats",   "commstats",   "close",   "trace_level",   "trace_mark",   "trace_message",   "trace_stop",   "trace_flush",   "trace_exit",   "block_begin",   "block_end",   "trace_marks"};#define N_RECORD_TYPES 22static char *blockTypeNames[] = {   "global_op",   "bcast0",   "bcast1",   "barrier"};#define N_BLOCK_TYPES 4#define PICL_TYPE_NAME_LEN     20#define PICL_HOST_NODE     -32768   /* for keeping track of what mode each process is in in this silly      format */typedef struct procMode_ {   recordTypeEnum mode;   int active;      /* for messages: */   int other_node;   int msg_type;   int msg_len;} procMode;typedef struct piclData_ {   Tcl_Interp *interp;   logFile *log;   double startTime, endTime;	/* earliest and latest events in the file */   int file_size;		/* size of the file */   int bytes_read;		/* # of bytes read so far */   int line_no;			/* current line # */   int isFirstTime;		/* is this the first line to be read? */   int hasHostNode;		/* does this tracefile have host node info				   in it? */   int maxProc;			/* largest process # */      /* When a time-consuming event occurs, such as a send, two compstats	 records will be generated; one at the start of the send, and	 one at the end.  So, when one of these time-consuming events occurs,	 log the beginning of a state, and save what kind it is, so when	 a compstats event comes in, we know what kind of state to	 associate it with.  When this first compstats comes in, mark	 this process as 'active'.  When the second compstats comes in,	 log the end of a state, and set the process back to normal. */   procMode *mode;		/* Allocate this to have on element for				   each process.  Store the mode each				   process is in. */      /* to mesh will the rest of Upshot, every action that will take	 up time must be mapped to a 'state'.  A new state definition	 is created with a call to State_AddDef().  This will return	 a state definition # that we should hang onto.  These arrays	 will hold state definition #'s or -1 if a state hasn't been	 created for the event type yet. */				/* state number for each record type */				/* if no state created yet, set to -1 */   int recordType_state_no[N_RECORD_TYPES];				/* state number for each block type */				/* 0 - 3 will refer to the collective ops, */				/* 4+ will be for user-defined states */   int blockType_state_no[N_BLOCK_TYPES + PICL_MAX_TASK_NO];   } piclData;typedef struct piclLineData_ {   int line_no;			/* line # */   recordTypeEnum type;		/* recordtype of event */   double clock;		/* time of the event */   int node;			/* node on which the event occurred */   int other_node;		/* for sends, the receiver; for receives, */				/* the sender */   int msg_type;		/* message type */   int msg_len;			/* length of message in bytes */   int type_no;			/* user-defined event # */   int block_type;		/* for block start/end events, the type of */				/* block: barrier, bcast0, user-defined, ... */   } piclLineData;  /* Open up a picl instance */static piclData *Create ANSI_ARGS(( logFile *log ));/* go through the tracefile, getting the first&last timestamps,   number of processes, and list of all the states that will be used */static int Preprocess ANSI_ARGS(( piclData *picl ));/* load the tracefile into memory */static int Load ANSI_ARGS(( piclData *picl ));/* Close picl-specific tracefile info, but leave the main logfile   information */static int Close ANSI_ARGS(( piclData *picl ));/* Get one word from the given stream, returning -1 if EOF reached, 0   if end-of-line, or the length of the word read.  If EOL read, increment   picl->line_no. */static int GetWord ANSI_ARGS(( piclData *picl, FILE *fp, char *wordbuf,			  int maxlen ));/* Given a record type and, if it is a block_begin or block_end,   a block type, create a string that will define this state.   'description' should point to at least PICL_TYPE_NAME_LEN bytes. *//*static int GetRecordTypeDesc ANSI_ARGS(( piclData *picl, int recordType,				    int blockType, char *description ));*//* Given a record type description, return the record type number or   -1 for an invalid type */static recordTypeEnum GetRecordTypeFromVerbose ANSI_ARGS(( char *str ));/* Get one line from the tracefile, parsing the data into 'line'.   Return -1 on EOF, 0 on blank line, and the length of the line   on success. */static int GetLine ANSI_ARGS(( piclData *picl, FILE *fp, piclLineData *line ));/* Create a state definition, if one hasn't been created already, for   the given record type of block type. */static int AddState ANSI_ARGS(( piclData *picl,  int recordType, int blockType ));/*   Given a record type and, if needed, a block type, return the state   definition number for the state represented.*/static int GetStateNo ANSI_ARGS(( piclData *picl, int recordType, int blockType ));/*   Mark the start of a state.*/static int StartState ANSI_ARGS(( piclData *picl, int node, double time,			     int recordType, int blockType ));/*   Mark the end of a state.*/static int EndState ANSI_ARGS(( piclData *picl, int node, double time,			   int recordType, int blockType ));int Picl_Open( log )logFile *log;{  piclData *picl;  picl = Create( log );  if (!picl) {    Tcl_SetResult( log->interp, "Out of memory opening picl tracefile",		   TCL_STATIC );    return TCL_ERROR;  }  if (Preprocess( picl ) != TCL_OK) goto err;  if (Load( picl ) != TCL_OK) goto err;  Close( picl );  return TCL_OK; err:  Close( picl );  return TCL_ERROR;}static piclData *Create( log )logFile *log;{   piclData *picl;   struct stat statBuf;   int i;      /* get the size of the file, complain if we can't. */   if (stat( log->filename, &statBuf ) == -1) {      Tcl_AppendResult( log->interp, "Couldn't get the size of ",		       log->filename, (char*)0 );      return 0;   }   picl = (piclData*)malloc( sizeof( piclData ) );   if (!picl) return 0;   picl->interp = log->interp;   picl->log = log;   picl->isFirstTime = 1;	/* set only for the first line */   picl->line_no = 1;		/* start counting at line 1 */   picl->bytes_read = 0;	/* nothing read so far */   picl->file_size = statBuf.st_size; /* save the size of the file */   picl->hasHostNode = 0;	/* assume no host node unless -32768 events				   are found */      /* set all state definition #'s to 0 - nobody has created a state	 for themselves yet.  */   for (i=0; i<N_RECORD_TYPES; i++) {      picl->recordType_state_no[i] = -1;   }   for (i=0; i<N_BLOCK_TYPES + PICL_MAX_TASK_NO; i++) {      picl->blockType_state_no[i] = -1;   }   return picl;}/*   Get one word from the input stream, returning 0 if the end of the line   was reached and read, -1 if EOF reached, or a the number of characters   in the word.*/static int GetWord( picl, fp, wordbuf, maxlen )piclData *picl;FILE *fp;char *wordbuf;int maxlen;{   int len, c;      /* set to output word buffer to a zero-length string */   wordbuf[0] = 0;   c = getc( fp );   picl->bytes_read++;      /* strip out space between words */   while (c != '\n' && isspace( c )) {      c = getc( fp );      picl->bytes_read++;   }      /* if EOL reached, return 0 */   if (c == '\n') {      picl->line_no++;      return 0;   }      /* get the word, stopping at newline, space, or EOF */   len = 0;   while (c != '\n' && c != EOF && !isspace( c )) {      wordbuf[len++] = c;      c = getc( fp );      picl->bytes_read++;   }      /* If we hit the end of the line or file and nothing has been read yet,         return 0.  If something has been read, return that and push	 the newline back into the stream */   if (c == '\n' || c == EOF) {      if (len) {	 picl->bytes_read--;	 ungetc( c, fp );      } else {	 wordbuf[0] = 0;	    /* return 0 if newline, -1 if EOF */	 if (c == '\n') {	    picl->line_no++;	    return 0;	 } else {	    return -1;	 }      }   }      /* terminate the string */   wordbuf[len] = 0;      /* return the # of characters in the word */   return len;}   /* flush input through the end of the line */static int GetEOL( picl, fp )piclData *picl;FILE *fp;{   while (getc( fp ) != '\n') picl->bytes_read++;   picl->line_no++;   return TCL_OK;}/*   Given a record type (and block type, if applicable),   return a string describing that block type.   The 'desc' parameter should point to at least   PICL_TYPE_NAME_LEN characters of usable memory.*/static int GetRecordTypeDesc( picl, recordType, blockType, description )piclData *picl;			/* all logfile info */int recordType;			/* record type */int blockType;			/* if record type==block_{start,end}, specify				   the block type, be it a collective				   operation or a 'task #' */char *description;		/* where to store the description */{   if (recordType < block_begin) {         /* one of the standard record types, which start number at 1 */      strcpy( description, recordTypeNames[recordType-1] );   } else {         /* a block_begin or block_end */      if (blockType < 0) {            /* one of the collective operations */            /* these are numbered from -4 to -1.  Remap this into 0 - 3 */	 strcpy( description, blockTypeNames[blockType+4] );      } else {	    /* a user-defined task #, from 0 to whatever.  Scale it back. */	 blockType %= PICL_MAX_TASK_NO;	 sprintf( description, "state_%d", blockType );      }   }   return 0;}/*   Given a string form of a record type, such as "trace_start", return   the recordTypeEnum index to this record type.  Return -1   if not recognized.*/static recordTypeEnum GetRecordTypeFromVerbose( str )char *str;{   int i;   for (i=0; i<N_RECORD_TYPES; i++) {      if (!strcmp( recordTypeNames[i], str )) {	 return (recordTypeEnum)i;      }   }

⌨️ 快捷键说明

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