📄 trace.c
字号:
/* PSPH - Parallel SPH program
* Bradley Smith, and Lou Baker, Dagonet Software
*/
static char sccs_id[] = "@(#) /home/bsmith/src/psph/SCCS/s.trace.c 1.3 94/01/06";
/* routines to implement a picl
* -style tracing feature
* NOT compatible with ParaGraph!
*
* L. Baker DAGONET SOFTWARE 11/93
*
*
* assumes an external char *CurDir;
*
*
* HOST = MASTER in Master/Slave model (assumed)
*
*
* caveat: recv has only 1023 bytes for msg! might have to up this.
* Also, potential problems if "host" does not generate traces often
* to recover trace messages from other slave nodes.
*
*
*/
#define TRACE
#ifdef TRACE
#define PICLCODE
#include "all.h"
/* Generic rank */
static int MyRank;
/* below only for node zero. wasted space otherwise. Not much though*/
static char TraceFileName[NAMESIZE];
static FILE *TraceFileP=NULL;
static long int tracekt= 0l;
static struct traceitem *TraceBuffer;
static int TraceBufferHolds=0,TraceBufferSize=0, FlushSize;
/* Definitions */
#define Host() (MyRank == 0)
static tracewrite(int mark,Time *t,char * msg);
void MPI_WriteTrace(struct traceitem *str, int bytecount);
int traceon_picl=0,tracelevel_picl;/* do not make static */
void traceon(){traceon_picl=1; tracemark(TraceTRACE_START);}
void traceoff(){ tracemark(TraceTRACE_FINISH);traceon_picl=0;}
void sync0()
{
MPI_Barrier(MPI_COMM_WORLD);
}
void TraceInit( char *tracefile, int format)
{
/* Get my rank */
MPI_Comm_rank(MPI_COMM_WORLD, &MyRank);
/* open trace file. format ignored, similar to keywd(verbose) NOT ParaGraph(=0) */
if(Host())
{
strncpy(TraceFileName,tracefile,NAMESIZE-1);
/* no translation CR/LF */
TraceFileP=fopen(tracefile,"wb");
if(TraceFileP==NULL)
{
ReportError("TraceInit: Open Failed\n",FALSE);
return;
}
}
return;
}
void TraceExit()
{
traceflush();
traceoff();
/* do not close file (if host) as children might not have
all responded yet */
return;
}
void traceenable(char *tracefile,int format){TraceInit(tracefile,format);}
void traceexit(){TraceExit();}
void traceclose()
{
/* close trace file if Host */
if(Host())
fclose(TraceFileP);
}
void traceflush()
{/* flush buffer*/
/*need to account for time tracing, particularly when sending data!
time filling buffers, etc. probably negligible
*/
Time start,st,end,ed;
#ifdef DEBUG
/*Debug(" traceflush called kt=%d Rank=%d\n",TraceBufferHolds,MyRank);
*/
#endif
st=time(&start);
/*send data!*/
MPI_WriteTrace(TraceBuffer,sizeof(struct traceitem)*TraceBufferHolds);
tracekt += TraceBufferHolds;
TraceBufferHolds=0;
ed=time(&end);
#ifdef DEBUG
/*Debug(" traceflush before writes Holds=%d Rank=%d\n",TraceBufferHolds,MyRank);
*/
#endif
/* this recursion should be allowed but may be dangerous*/
tracewrite(TraceTRACE_FLUSH,&start,NULL);
tracewrite(TraceTRACE_FLUSHD,&end,NULL);
#ifdef DEBUG
/*Debug(" traceflush after tracewrites %d=Holds Rank=%d\n",TraceBufferHolds,MyRank);
*/
#endif
return;
}
void tracehost(int tracesize, int flush)
{
tracenode(tracesize,flush, FALSE);/* DO NOT SYNC*/
return ;/* DUMMY- Delta, etc not Host/Node machine*/
}
void traceinfo(int *remaining, int *event, int *compstats, int *commstats)
{
int hold;
hold=tracelevel_picl;
*event= hold & 0x7;
hold>>=3;
*compstats=hold & 0x7;
hold>>=3;
*commstats=hold;
*remaining= (TraceBufferHolds-TraceBufferSize -SAFTEY);
return;
}
void tracelevel(int event, int compstats, int commstats)
{
if(commstats>3)commstats=3;
if(event>4)event=4;
if(compstats>4)commstats=4;
tracelevel_picl = event |(compstats<<3)|(commstats<<6);
return;/* DUMMY ParaGraph only wants (4,4,0) anyway! 4 should behave same as 3*/
}
static tracewrite(int mark,Time *t, char * msg)
{
int len;
Time timer;
struct traceitem *event;
#ifdef DEBUG
/*Debug(" tracewrite called mark=%d Rank=%d\n",mark,MyRank);
*/
#endif
if(TraceBuffer==NULL)return;
#ifdef DEBUG
/*Debug(" Tracewrite entered Holds=%d\n",TraceBufferHolds);
*/
#endif
event= &(TraceBuffer[TraceBufferHolds]);
if(t==NULL)
timer= time(&(event->when)); /*return value stored in timer */
else
{
/*
#if (sizeof( time_t)<4)
*/
event->when= *t;
/* CAVEAT: this assumes Time ie time_t is atomic variable!!!!!!!!!!!!*/
/*
#else
len= sizeof(time_t);
memcpy(&(event->when),t,len);
#endif
*/
}
event->who= MPI_COMM_WORLD;
event->what= mark;
if( msg==NULL)
{
if(CurDir!=NULL)strncpy(event->where, CurDir,MaxCurDirS);
}
else
{
strncpy(event->where,msg,MaxCurDirS);
}
TraceBufferHolds++;
#ifdef DEBUG
/*Debug(" tracewrite before flush Holds=%d\n",TraceBufferHolds);
*/
#endif
if(TraceBufferHolds >= FlushSize) traceflush();
#ifdef DEBUG
/*Debug(" tracewrite after flush Holds=%d\n",TraceBufferHolds);
*/
#endif
return 0;
}
void tracemark(int marktype)
{/* system or user-defined event */
/*write to buffer*/
int rv;
#ifdef DEBUG
/*Debug(" tracemark called type=%d Rank=%d\n",marktype,MyRank);
*/
#endif
if(!traceon_picl)return;
rv=tracewrite(marktype,NULL,NULL);
#ifdef DEBUG
/*Debug(" tracemark returning type=%d Rank=%d twrv=%d\n",marktype,MyRank,rv);
*/
#endif
}
void tracemsg(char *message)
{/* user msg */
if(!traceon_picl)return;
#ifdef DEBUG
/*
Debug(" tracemsg Rank=%d\n",MyRank);
*/
#endif
tracewrite(TraceUSR_MSG, NULL,message);
#ifdef DEBUG
/*
Debug(" tracemsg returning %s Rank=%d\n",message,MyRank);
*/
#endif
return;
}
void tracenode(int tracesize,int flush, int sync)
{
int need_size;
/* establish buffer. flush automatically=1 <=0 immediate.
if sync=1 synchronize first */
#ifdef DEBUG
/*Debug(" tracenode %d Rank=%d\n",tracesize,MyRank);
*/
#endif
need_size = tracesize;
TraceBufferSize=tracesize;
FlushSize=TraceBufferSize;
TraceBufferHolds=0;
if(flush <=0) FlushSize=3;/* flush each msg along with its FLUSH msgs */
/*if(flush==1)FlushSize=1;*/
if(FlushSize<3) FlushSize=3;
TraceBuffer=(struct traceitem *)malloc(need_size * sizeof(struct traceitem ));
if(TraceBuffer==NULL)
{/* send error message */
ReportError("tracenode msg buffer malloc falied\n",FALSE);
exit(1); /* abort? */
}
if(sync)
{
sync0();
}
traceon();
#ifdef DEBUG
/*Debug(" tracenode returning %d Rank=%d\n",TraceBufferSize,MyRank);
*/
#endif
return;
}
Event traceMaxEvent(){return TraceMAXEVENT;}
static FILE *out=NULL;
void MPI_WriteTrace(struct traceitem *str, int bytecount)
{
int rank,flag;
int count,i;
MPI_Status status;
struct traceitem *ti;
char s[1024];
#define TRACE_TAG 4095
#ifdef DEBUG
/*Debug(" WriteTrace Entered Rank=%d %d\n",MyRank, bytecount);
*/
if(Host())printf(" WriteTraceEntered Host %d %d\n",bytecount, sizeof(struct traceitem));
#endif
flag = TRUE;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#ifdef DEBUG
if(rank > 0)
{
/* temporary since str is struct traceitem
sprintf(s,"[%2d] %s", rank,str);
str = s;
*/
}
if(!out)/* && Host added by Baker */
out=fopen("/home/baker/psph.trc","a");
if(out && Host())
{
count = bytecount/sizeof(struct traceitem);
ti=str;
for(i=0;i<count;i++,ti++)
fprintf(out,"host:Id=%d event=%d\n",ti->who,ti->what);
}
if(!out && !rank){printf(" cannot open psph.trc\n");fflush(stdout);}
#endif
if(rank == 0)
{
/* Print stuff out */
while(flag)
{
/* printf(" TOP TRACE DEBUG: tracemsg count=%ld\n",tracekt);
fflush(stdout);
*/
MPI_Iprobe(MPI_ANY_SOURCE, TRACE_TAG, MPI_COMM_WORLD, &flag,
&status);
if(!flag)
break;
MPI_Recv(s, 1023,MPI_CHAR, MPI_ANY_SOURCE,TRACE_TAG,MPI_COMM_WORLD, &status);
MPI_Get_count(status, MPI_CHAR, &count);
fwrite(s,count,1,TraceFileP);
fflush(TraceFileP);
tracekt += count/sizeof(struct traceitem) ;
/* printf(" TRACE DEBUG: tracemsg count=%ld\n",tracekt);
fflush(stdout);
*/
count = bytecount/sizeof(struct traceitem);
ti=s;
for(i=0;i<count;i++,ti++)
fprintf(out,"slave:Id=%d event=%d\n",ti->who,ti->what);
}
fwrite(str,bytecount,1,TraceFileP);
fflush(TraceFileP);
}
else
MPI_Send(str, bytecount, MPI_CHAR, 0, TRACE_TAG, MPI_COMM_WORLD);
#ifdef DEBUG
/*Debug(" WriteTrace Exiting Rank=%d %d\n",MyRank, bytecount);
*/
#endif
}
#endif /* TRACE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -