📄 picl.c
字号:
return (recordTypeEnum)-1;}/* Get one line of a picl tracefile, parsing data out of it. Return 0 on success, -1 on EOF, -2 on failure.*/static int GetLine( picl, fp, line )piclData *picl;FILE *fp;piclLineData *line;{ static char word[MAX_WORD_LEN]; int readStatus; int verbose; #define GET_WORD \ if (GetWord( picl, fp, word, MAX_WORD_LEN ) < 1) \ goto format_error /* clear the members of the line info structure that might not get set */ line->msg_type = line->msg_len = line->type_no = line->block_type = line->other_node = 0; /* skip over blank lines */ while ((readStatus = GetWord( picl, fp, word, MAX_WORD_LEN )) == 0); /* end of file */ if (readStatus == -1) { return -1; } line->line_no = picl->line_no; /* if the first character is a letter, this is a verbose line */ verbose = isalpha( word[0] ); line->type = min_recordType; if (verbose) { /* interpret the record type */ line->type = GetRecordTypeFromVerbose( word ); } else { line->type = (recordTypeEnum)atoi( word ); } if (line->type >= max_recordType || line->type <= min_recordType ) { sprintf( picl->interp->result, "unrecognized record type in line %d", picl->line_no ); Tcl_AppendResult( picl->interp, " of ", picl->log->filename, (char*)0 ); return -2; } if (verbose) { /* skip the 'clock' label */ GET_WORD; } /* get # of seconds */ GET_WORD; line->clock = atoi( word ); /* get microseconds */ GET_WORD; line->clock += .000001 * atoi( word ); if (picl->isFirstTime) { picl->startTime = line->clock; picl->endTime = line->clock; picl->isFirstTime = 0; } else { if (line->clock < picl->startTime) { picl->startTime = line->clock; } else if (line->clock > picl->endTime) { picl->endTime = line->clock; } } if (verbose) { /* skip the 'node' label */ GET_WORD; } /* get the node # */ GET_WORD; line->node = atoi( word ); if (line->type == send || line->type == recv || line->type == recv_waking) { if (verbose) GET_WORD; /* skip "to"/"from" */ GET_WORD; line->other_node = atoi(word); if (verbose) GET_WORD; /* skip "type" */ GET_WORD; line->msg_type = atoi(word); if (verbose) GET_WORD; /* skip "lth" */ GET_WORD; line->msg_len = atoi(word); } else if (line->type == recv_blocking) { if (verbose) GET_WORD; /* skip "type" */ GET_WORD; line->msg_type = atoi(word); } else if (line->type == trace_mark) { if (verbose) GET_WORD; /* skip "type" */ GET_WORD; line->type_no = atoi(word); } else if (line->type == block_begin || line->type == block_end) { if (verbose) GET_WORD; /* skip block_type */ GET_WORD; line->block_type = atoi(word); } GetEOL( picl, fp ); return 0; format_error: sprintf( picl->interp->result, "Format error in line %d", picl->line_no ); Tcl_AppendResult( picl->interp, " of ", picl->log->filename, (char*)0 ); return -2;} static int Preprocess( picl )piclData *picl;{ FILE *fp; piclLineData line; fp = fopen( picl->log->filename, "r" ); picl->maxProc = 0; while (GetLine( picl, fp, &line ) == 0) { if (line.node > picl->maxProc) { picl->maxProc = line.node; } else if (line.node == PICL_HOST_NODE) { /* set flag marking that a host node is being represented */ picl->hasHostNode = 1; } /* if the state type occurs once, add it as an official new state type */ if (line.type == send || line.type == recv || line.type == recv_blocking || line.type == sync) { AddState( picl, line.type, 0 ); } else if (line.type == block_begin || line.type == block_end ) { /* a block marks the start and end of a collective operation */ AddState( picl, line.type, line.block_type ); } } /* set stuff needed by all the logfile routines */ picl->log->starttime = picl->startTime; picl->log->endtime = picl->endTime; /* if node=-32768 events were encountered, shift everyone up one to make way for a host node at 0 */ picl->log->np = picl->maxProc + 1 + picl->hasHostNode;#if DEBUG printf( "States defined:\n" ); for (i=0; i<N_RECORD_TYPES; i++) { char *name, *color, *bitmap; if (picl->recordType_state_no[i] != -1) { State_GetDef( picl->log->states, picl->recordType_state_no[i], &name, &color, &bitmap ); printf( " %d: %s %s %s\n", picl->recordType_state_no[i], name, color, bitmap ); } } for (i=0; i<N_BLOCK_TYPES + PICL_MAX_TASK_NO; i++) { char *name, *color, *bitmap; if (picl->blockType_state_no[i] != -1) { State_GetDef( picl->log->states, picl->blockType_state_no[i], &name, &color, &bitmap ); printf( " %d: %s %s %s\n", picl->blockType_state_no[i], name, color, bitmap ); } }#endif return TCL_OK;} /* GetRecordTypeDesc( picl, line.type, line.block_type, desc ); printf( "Line %d: type %d (%s), clock %f, node %d, %d %d %d %d %d\n", line.line_no, line.type, desc, line.clock, line.node, line.other_node, line.msg_type, line.msg_len, line.type_no, line.block_type );*/static int Close( picl )piclData *picl;{ free( (char*)picl ); return 0;}static int AddState( picl, recordType, blockType )piclData *picl;int recordType, blockType;{ char desc[PICL_TYPE_NAME_LEN]; if ((recordTypeEnum)recordType < block_begin) { /* normal record type */ /* recordType comes in starting at 1 */ recordType--; /* check if it's already been defined */ if (picl->recordType_state_no[recordType] == -1) { /* get string description of the type */ GetRecordTypeDesc( picl, recordType+1, blockType, desc ); /* add state definition */ picl->recordType_state_no[recordType] = State_AddDef( picl->log->states, (char*)0, (char*)0, desc ); } } else { /* block type */ /* wrap around user-defined types to a sane limit */ if (blockType >= 0) { blockType %= PICL_MAX_TASK_NO; } /* blockType comes in starting at -4 */ blockType += 4; /* check if it's already been defined */ if (picl->blockType_state_no[blockType] == -1) { /* get string description of the type */ GetRecordTypeDesc( picl, recordType, blockType-4, desc ); /* add state definition */ picl->blockType_state_no[blockType] = State_AddDef( picl->log->states, (char*)0, (char*)0, desc ); } } return TCL_OK;}static int Load( picl )piclData *picl;{ FILE *fp; piclLineData line; int np; int i; procMode *mode; fp = fopen( picl->log->filename, "r" ); np = Log_Np( picl->log ); /* let all the data gatherers that I'm comin' */ Event_DataInit( picl->log->events, np ); State_DataInit( picl->log->states, np ); Msg_DataInit( picl->log->msgs, np ); Process_DataInit( picl->log->processes, np ); /* allocate storage area for process mode info */ picl->mode = (procMode*)malloc( sizeof(procMode) * np ); if (!picl->mode) { Tcl_AppendResult( picl->interp, "Out of memory loading PICL file", (char *)0 ); return TCL_ERROR; } /* initialize process modes */ for (i=0; i<np; i++) { picl->mode[i].mode = min_recordType; } /* go through the logfile again */ while (GetLine( picl, fp, &line ) == 0) { /* if node=-32768 events were encountered, shift everyone up one to make way for a host node at 0 */ if (picl->hasHostNode) { if (line.node == PICL_HOST_NODE) { line.node = 0; } else { line.node++; } } /* get easy-access pointer the mode info */ mode = picl->mode + line.node; switch (line.type) { /* for events that will take some time */ case send: case recv: /* save message info */ mode->other_node = line.other_node; mode->msg_type = line.msg_type; mode->msg_len = line.msg_len; case probe: case sync: /* save this info for the followup compstats call */ mode->mode = line.type; mode->active = 0; /* these two don't rely on the compstats kludge */ case block_begin: case recv_blocking: /* mark the beginning of a state */ StartState( picl, line.node, line.clock, line.type, line.block_type ); break; case recv_waking: /* Ooo, a message finally came in! */ Msg_Recv( picl->log->msgs, line.node, line.other_node, line.clock, line.msg_type, line.msg_len ); /* just so the state from recv_blocking is used */ line.type = recv_blocking; case block_end: EndState( picl, line.node, line.clock, line.type, line.block_type ); break; case compstats: /* get easy-access pointer the mode info */ mode = picl->mode + line.node; /* make sure we really are waiting for something */ if (mode->mode != min_recordType) { /* if the process is not 'active' in this mode, this is the first compstats entry. Now it should be set to active, to wait for the second compstats entry. */ if (!mode->active) { mode->active = 1; } else { /* finally, the end of the state */ EndState( picl, line.node, line.clock, mode->mode, 0 ); /* if this was a message... */ if (mode->mode == send) { Msg_Send( picl->log->msgs, line.node, mode->other_node, line.clock, mode->msg_type, mode->msg_len ); } else if (mode->mode == recv) { Msg_Recv( picl->log->msgs, line.node, mode->other_node, line.clock, mode->msg_type, mode->msg_len ); } mode->active = 0; mode->mode = min_recordType; } } break; case min_recordType: case trace_start: case open: case load: case message: case commstats: case close: case trace_level: case trace_mark: case trace_message: case trace_stop: case trace_flush: case trace_exit: case trace_marks: case max_recordType: /* do nothing for these guys, but keep the compiler happy */ break; } /* switch */ } /* while */ free( (char*)picl->mode ); fclose( fp ); return 0;}/* Given a record and block type, return the state definition # created for this type of state.*/static int GetStateNo( picl, recordType, blockType )piclData *picl;int recordType, blockType;{ if ((recordTypeEnum)recordType < block_begin) { /* this is a normal record type */ /* recordType comes in starting at 1 */ return picl->recordType_state_no[recordType-1]; } else { /* wrap around big user-defined event types */ if (blockType >= 0) blockType %= PICL_MAX_TASK_NO; /* this is a block record type */ /* blockType comes in starting at -4 */ return picl->blockType_state_no[blockType+4]; }}static int StartState( picl, node, time, recordType, blockType )piclData *picl;int node, recordType, blockType;double time;{ State_Start( picl->log->states, GetStateNo( picl, recordType, blockType ), node, time ); return TCL_OK;}static int EndState( picl, node, time, recordType, blockType )piclData *picl;int node, recordType, blockType;double time;{ State_End( picl->log->states, GetStateNo( picl, recordType, blockType ), node, time ); return TCL_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -