Actual source code: eventLog.c
1: /* $Id: eventLog.c,v 1.3 2000/08/16 05:14:09 knepley Exp $ */
3: #include petsc.h
4: #include src/sys/src/plog/ptime.h
5: #include plog.h
7: /* Variables for the tracing logger */
8: extern FILE *tracefile;
9: extern int tracelevel;
10: extern char *traceblanks;
11: extern char tracespace[128];
12: extern PetscLogDouble tracetime;
14: /*----------------------------------------------- Creation Functions -------------------------------------------------*/
15: #undef __FUNCT__
17: /*@C
18: EventRegLogCreate - This creates a EventRegLog object.
20: Not collective
22: Input Parameter:
23: . eventLog - The EventRegLog
25: Level: beginner
27: .keywords: log, event, create
28: .seealso: EventRegLogDestroy(), StageLogCreate()
29: @*/
30: int EventRegLogCreate(EventRegLog *eventLog) {
31: EventRegLog l;
32: int ierr;
35: PetscNew(struct _EventRegLog, &l);
36: l->numEvents = 0;
37: l->maxEvents = 100;
38: PetscMalloc(l->maxEvents * sizeof(EventRegInfo), &l->eventInfo);
39: *eventLog = l;
40: return(0);
41: }
43: #undef __FUNCT__
45: /*@C
46: EventRegLogDestroy - This destroys a EventRegLog object.
48: Not collective
50: Input Paramter:
51: . eventLog - The EventRegLog
53: Level: beginner
55: .keywords: log, event, destroy
56: .seealso: EventRegLogCreate()
57: @*/
58: int EventRegLogDestroy(EventRegLog eventLog) {
59: int e;
63: for(e = 0; e < eventLog->numEvents; e++) {
64: PetscFree(eventLog->eventInfo[e].name);
65: }
66: PetscFree(eventLog->eventInfo);
67: PetscFree(eventLog);
68: return(0);
69: }
71: #undef __FUNCT__
73: /*@C
74: EventPerfLogCreate - This creates a EventPerfLog object.
76: Not collective
78: Input Parameter:
79: . eventLog - The EventPerfLog
81: Level: beginner
83: .keywords: log, event, create
84: .seealso: EventPerfLogDestroy(), StageLogCreate()
85: @*/
86: int EventPerfLogCreate(EventPerfLog *eventLog) {
87: EventPerfLog l;
88: int ierr;
91: PetscNew(struct _EventPerfLog, &l);
92: l->numEvents = 0;
93: l->maxEvents = 100;
94: PetscMalloc(l->maxEvents * sizeof(EventPerfInfo), &l->eventInfo);
95: *eventLog = l;
96: return(0);
97: }
99: #undef __FUNCT__
101: /*@C
102: EventPerfLogDestroy - This destroys a EventPerfLog object.
104: Not collective
106: Input Paramter:
107: . eventLog - The EventPerfLog
109: Level: beginner
111: .keywords: log, event, destroy
112: .seealso: EventPerfLogCreate()
113: @*/
114: int EventPerfLogDestroy(EventPerfLog eventLog) {
118: PetscFree(eventLog->eventInfo);
119: PetscFree(eventLog);
120: return(0);
121: }
123: /*------------------------------------------------ General Functions -------------------------------------------------*/
124: #undef __FUNCT__
126: /*@C
127: EventPerfInfoClear - This clears a EventPerfInfo object.
129: Not collective
131: Input Paramter:
132: . eventInfo - The EventPerfInfo
134: Level: beginner
136: .keywords: log, event, destroy
137: .seealso: EventPerfLogCreate()
138: @*/
139: int EventPerfInfoClear(EventPerfInfo *eventInfo) {
141: eventInfo->id = -1;
142: eventInfo->active = PETSC_TRUE;
143: eventInfo->visible = PETSC_TRUE;
144: eventInfo->depth = 0;
145: eventInfo->count = 0;
146: eventInfo->flops = 0.0;
147: eventInfo->time = 0.0;
148: eventInfo->numMessages = 0.0;
149: eventInfo->messageLength = 0.0;
150: eventInfo->numReductions = 0.0;
151: return(0);
152: }
154: #undef __FUNCT__
156: /*@C
157: EventPerfInfoCopy - Copy the activity and visibility data in eventInfo to outInfo
159: Not collective
161: Input Paramter:
162: . eventInfo - The input EventPerfInfo
164: Output Paramter:
165: . outInfo - The output EventPerfInfo
167: Level: beginner
169: .keywords: log, event, copy
170: .seealso: EventPerfInfoClear()
171: @*/
172: int EventPerfInfoCopy(EventPerfInfo *eventInfo, EventPerfInfo *outInfo) {
174: outInfo->id = eventInfo->id;
175: outInfo->active = eventInfo->active;
176: outInfo->visible = eventInfo->visible;
177: return(0);
178: }
180: #undef __FUNCT__
182: /*@C
183: EventPerfLogEnsureSize - This ensures that a EventPerfLog is at least of a certain size.
185: Not collective
187: Input Paramters:
188: + eventLog - The EventPerfLog
189: - size - The size
191: Level: intermediate
193: .keywords: log, event, size, ensure
194: .seealso: EventPerfLogCreate()
195: @*/
196: int EventPerfLogEnsureSize(EventPerfLog eventLog, int size) {
197: EventPerfInfo *eventInfo;
198: int ierr;
201: while(size > eventLog->maxEvents) {
202: PetscMalloc(eventLog->maxEvents*2 * sizeof(EventPerfInfo), &eventInfo);
203: PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventPerfInfo));
204: PetscFree(eventLog->eventInfo);
205: eventLog->eventInfo = eventInfo;
206: eventLog->maxEvents *= 2;
207: }
208: while(eventLog->numEvents < size) {
209: EventPerfInfoClear(&eventLog->eventInfo[eventLog->numEvents++]);
210: }
211: return(0);
212: }
214: /*--------------------------------------------- Registration Functions ----------------------------------------------*/
215: #undef __FUNCT__
217: /*@C
218: EventRegLogRegister - Registers an event for logging operations in an application code.
220: Not Collective
222: Input Parameters:
223: + eventLog - The EventLog
224: . ename - The name associated with the event
225: - cookie - The cookie associated to the class for this event
227: Output Parameter:
228: . event - The event
230: Example of Usage:
231: .vb
232: int USER_EVENT;
233: int user_event_flops;
234: PetscLogEventRegister(&USER_EVENT,"User event name");
235: PetscLogEventBegin(USER_EVENT,0,0,0,0);
236: [code segment to monitor]
237: PetscLogFlops(user_event_flops);
238: PetscLogEventEnd(USER_EVENT,0,0,0,0);
239: .ve
241: Notes:
242: PETSc automatically logs library events if the code has been
243: compiled with -DPETSC_USE_LOG (which is the default) and -log,
244: -log_summary, or -log_all are specified. PetscLogEventRegister() is
245: intended for logging user events to supplement this PETSc
246: information.
248: PETSc can gather data for use with the utilities Upshot/Nupshot
249: (part of the MPICH distribution). If PETSc has been compiled
250: with flag -DPETSC_HAVE_MPE (MPE is an additional utility within
251: MPICH), the user can employ another command line option, -log_mpe,
252: to create a logfile, "mpe.log", which can be visualized
253: Upshot/Nupshot.
255: Level: intermediate
257: .keywords: log, event, register
258: .seealso: PetscLogEventBegin(), PetscLogEventEnd(), PetscLogFlops(), PetscLogEventMPEActivate(), PetscLogEventMPEDeactivate(),
259: EventLogActivate(), EventLogDeactivate()
260: @*/
261: int EventRegLogRegister(EventRegLog eventLog, const char ename[], int cookie, PetscEvent *event) {
262: EventRegInfo *eventInfo;
263: char *str;
264: int e;
265: int ierr;
270: /* Should check cookie I think */
271: e = eventLog->numEvents++;
272: if (eventLog->numEvents > eventLog->maxEvents) {
273: PetscMalloc(eventLog->maxEvents*2 * sizeof(EventRegInfo), &eventInfo);
274: PetscMemcpy(eventInfo, eventLog->eventInfo, eventLog->maxEvents * sizeof(EventRegInfo));
275: PetscFree(eventLog->eventInfo);
276: eventLog->eventInfo = eventInfo;
277: eventLog->maxEvents *= 2;
278: }
279: PetscStrallocpy(ename, &str);
280: eventLog->eventInfo[e].name = str;
281: eventLog->eventInfo[e].cookie = cookie;
282: #if defined(PETSC_HAVE_MPE)
283: if (UseMPE) {
284: char *color;
285: int rank, beginID, endID;
287: beginID = MPE_Log_get_event_number();
288: endID = MPE_Log_get_event_number();
289: eventLog->eventInfo[e].mpe_id_begin = beginID;
290: eventLog->eventInfo[e].mpe_id_end = endID;
291: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
292: if (!rank) {
293: PetscLogGetRGBColor(&color);
294: MPE_Describe_state(beginID, endID, str, color);
295: }
296: }
297: #endif
298: *event = e;
299: return(0);
300: }
302: /*---------------------------------------------- Activation Functions -----------------------------------------------*/
303: #undef __FUNCT__
305: /*@C
306: EventPerfLogActivate - Indicates that a particular event should be logged.
308: Not Collective
310: Input Parameters:
311: + eventLog - The EventPerfLog
312: - event - The event
314: Usage:
315: .vb
316: EventPerfLogDeactivate(log, VEC_SetValues);
317: [code where you do not want to log VecSetValues()]
318: EventPerfLogActivate(log, VEC_SetValues);
319: [code where you do want to log VecSetValues()]
320: .ve
322: Note:
323: The event may be either a pre-defined PETSc event (found in
324: include/petsclog.h) or an event number obtained with EventRegLogRegister().
326: Level: advanced
328: .keywords: log, event, activate
329: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogDeactivate()
330: @*/
331: int EventPerfLogActivate(EventPerfLog eventLog, PetscEvent event) {
333: eventLog->eventInfo[event].active = PETSC_TRUE;
334: return(0);
335: }
337: #undef __FUNCT__
339: /*@C
340: EventPerfLogDeactivate - Indicates that a particular event should not be logged.
342: Not Collective
344: Input Parameters:
345: + eventLog - The EventPerfLog
346: - event - The event
348: Usage:
349: .vb
350: EventPerfLogDeactivate(log, VEC_SetValues);
351: [code where you do not want to log VecSetValues()]
352: EventPerfLogActivate(log, VEC_SetValues);
353: [code where you do want to log VecSetValues()]
354: .ve
356: Note:
357: The event may be either a pre-defined PETSc event (found in
358: include/petsclog.h) or an event number obtained with EventRegLogRegister().
360: Level: advanced
362: .keywords: log, event, activate
363: .seealso: PetscLogEventMPEDeactivate(), PetscLogEventMPEActivate(), EventPerfLogActivate()
364: @*/
365: int EventPerfLogDeactivate(EventPerfLog eventLog, PetscEvent event) {
367: eventLog->eventInfo[event].active = PETSC_FALSE;
368: return(0);
369: }
371: #undef __FUNCT__
373: /*@C
374: EventPerfLogActivateClass - Activates event logging for a PETSc object class.
376: Not Collective
378: Input Parameters:
379: + eventLog - The EventPerfLog
380: . eventRegLog - The EventRegLog
381: - cookie - The class id, for example MAT_COOKIE, SNES_COOKIE,
383: Level: developer
385: .seealso: EventPerfLogDeactivateClass(), EventPerfLogActivate(), EventPerfLogDeactivate()
386: @*/
387: int EventPerfLogActivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, int cookie) {
388: int e;
391: for(e = 0; e < eventLog->numEvents; e++) {
392: int c = eventRegLog->eventInfo[e].cookie;
394: if (c == cookie) eventLog->eventInfo[e].active = PETSC_TRUE;
395: }
396: return(0);
397: }
399: #undef __FUNCT__
401: /*@C
402: EventPerfLogDeactivateClass - Deactivates event logging for a PETSc object class.
404: Not Collective
406: Input Parameters:
407: + eventLog - The EventPerfLog
408: . eventRegLog - The EventRegLog
409: - cookie - The class id, for example MAT_COOKIE, SNES_COOKIE,
411: Level: developer
413: .seealso: EventPerfLogDeactivateClass(), EventPerfLogDeactivate(), EventPerfLogActivate()
414: @*/
415: int EventPerfLogDeactivateClass(EventPerfLog eventLog, EventRegLog eventRegLog, int cookie) {
416: int e;
419: for(e = 0; e < eventLog->numEvents; e++) {
420: int c = eventRegLog->eventInfo[e].cookie;
422: if (c == cookie) eventLog->eventInfo[e].active = PETSC_FALSE;
423: }
424: return(0);
425: }
427: /*------------------------------------------------ Query Functions --------------------------------------------------*/
428: #undef __FUNCT__
430: /*@C
431: EventPerfLogSetVisible - This function determines whether an event is printed during PetscLogPrintSummary()
433: Not Collective
435: Input Parameters:
436: + eventLog - The EventPerfLog
437: . event - The event to log
438: - isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
440: Database Options:
441: . -log_summary - Activates log summary
443: Level: intermediate
445: .keywords: log, visible, event
446: .seealso: EventPerfLogGetVisible(), EventRegLogRegister(), StageLogGetEventLog()
447: @*/
448: int EventPerfLogSetVisible(EventPerfLog eventLog, PetscEvent event, PetscTruth isVisible) {
450: eventLog->eventInfo[event].visible = isVisible;
451: return(0);
452: }
454: #undef __FUNCT__
456: /*@C
457: EventPerfLogGetVisible - This function returns whether an event is printed during PetscLogPrintSummary()
459: Not Collective
461: Input Parameters:
462: + eventLog - The EventPerfLog
463: - event - The event id to log
465: Output Parameter:
466: . isVisible - The visibility flag, PETSC_TRUE for printing, otherwise PETSC_FALSE (default is PETSC_TRUE)
468: Database Options:
469: . -log_summary - Activates log summary
471: Level: intermediate
473: .keywords: log, visible, event
474: .seealso: EventPerfLogSetVisible(), EventRegLogRegister(), StageLogGetEventLog()
475: @*/
476: int EventPerfLogGetVisible(EventPerfLog eventLog, PetscEvent event, PetscTruth *isVisible) {
479: *isVisible = eventLog->eventInfo[event].visible;
480: return(0);
481: }
483: /*------------------------------------------------ Action Functions -------------------------------------------------*/
484: #undef __FUNCT__
486: int PetscLogEventBeginDefault(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
487: StageLog stageLog;
488: EventPerfLog eventLog;
489: int stage;
490: int ierr;
493: PetscLogGetStageLog(&stageLog);
494: StageLogGetCurrent(stageLog, &stage);
495: StageLogGetEventPerfLog(stageLog, stage, &eventLog);
496: /* Check for double counting */
497: eventLog->eventInfo[event].depth++;
498: if (eventLog->eventInfo[event].depth > 1) return(0);
499: /* Log performance info */
500: eventLog->eventInfo[event].count++;
501: PetscTimeSubtract(eventLog->eventInfo[event].time);
502: eventLog->eventInfo[event].flops -= _TotalFlops;
503: eventLog->eventInfo[event].numMessages -= irecv_ct + isend_ct + recv_ct + send_ct;
504: eventLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
505: eventLog->eventInfo[event].numReductions -= allreduce_ct;
506: return(0);
507: }
509: #undef __FUNCT__
511: int PetscLogEventEndDefault(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
512: StageLog stageLog;
513: EventPerfLog eventLog;
514: int stage;
515: int ierr;
518: PetscLogGetStageLog(&stageLog);
519: StageLogGetCurrent(stageLog, &stage);
520: StageLogGetEventPerfLog(stageLog, stage, &eventLog);
521: /* Check for double counting */
522: eventLog->eventInfo[event].depth--;
523: if (eventLog->eventInfo[event].depth > 0) {
524: return(0);
525: } else if (eventLog->eventInfo[event].depth < 0) {
526: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
527: }
528: /* Log performance info */
529: PetscTimeAdd(eventLog->eventInfo[event].time);
530: eventLog->eventInfo[event].flops += _TotalFlops;
531: eventLog->eventInfo[event].numMessages += irecv_ct + isend_ct + recv_ct + send_ct;
532: eventLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
533: eventLog->eventInfo[event].numReductions += allreduce_ct;
534: return(0);
535: }
537: #undef __FUNCT__
539: int PetscLogEventBeginComplete(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
540: StageLog stageLog;
541: EventRegLog eventRegLog;
542: EventPerfLog eventPerfLog;
543: Action *tmpAction;
544: PetscLogDouble start, end;
545: PetscLogDouble curTime;
546: int stage;
547: int ierr;
550: /* Dynamically enlarge logging structures */
551: if (numActions >= maxActions) {
552: PetscTime(start);
553: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
554: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
555: PetscFree(actions);
556: actions = tmpAction;
557: maxActions *= 2;
558: PetscTime(end);
559: BaseTime += (end - start);
560: }
561: /* Record the event */
562: PetscLogGetStageLog(&stageLog);
563: StageLogGetCurrent(stageLog, &stage);
564: StageLogGetEventRegLog(stageLog, &eventRegLog);
565: StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
566: PetscTime(curTime);
567: if (logActions == PETSC_TRUE) {
568: actions[numActions].time = curTime - BaseTime;
569: actions[numActions].action = ACTIONBEGIN;
570: actions[numActions].event = event;
571: actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
572: if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
573: if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
574: if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
575: actions[numActions].flops = _TotalFlops;
576: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
577: numActions++;
578: }
579: /* Check for double counting */
580: eventPerfLog->eventInfo[event].depth++;
581: if (eventPerfLog->eventInfo[event].depth > 1) return(0);
582: /* Log the performance info */
583: eventPerfLog->eventInfo[event].count++;
584: eventPerfLog->eventInfo[event].time -= curTime;
585: eventPerfLog->eventInfo[event].flops -= _TotalFlops;
586: eventPerfLog->eventInfo[event].numMessages -= irecv_ct + isend_ct + recv_ct + send_ct;
587: eventPerfLog->eventInfo[event].messageLength -= irecv_len + isend_len + recv_len + send_len;
588: eventPerfLog->eventInfo[event].numReductions -= allreduce_ct;
589: return(0);
590: }
592: #undef __FUNCT__
594: int PetscLogEventEndComplete(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
595: StageLog stageLog;
596: EventRegLog eventRegLog;
597: EventPerfLog eventPerfLog;
598: Action *tmpAction;
599: PetscLogDouble start, end;
600: PetscLogDouble curTime;
601: int stage;
602: int ierr;
605: /* Dynamically enlarge logging structures */
606: if (numActions >= maxActions) {
607: PetscTime(start);
608: PetscMalloc(maxActions*2 * sizeof(Action), &tmpAction);
609: PetscMemcpy(tmpAction, actions, maxActions * sizeof(Action));
610: PetscFree(actions);
611: actions = tmpAction;
612: maxActions *= 2;
613: PetscTime(end);
614: BaseTime += (end - start);
615: }
616: /* Record the event */
617: PetscLogGetStageLog(&stageLog);
618: StageLogGetCurrent(stageLog, &stage);
619: StageLogGetEventRegLog(stageLog, &eventRegLog);
620: StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
621: PetscTime(curTime);
622: if (logActions == PETSC_TRUE) {
623: actions[numActions].time = curTime - BaseTime;
624: actions[numActions].action = ACTIONEND;
625: actions[numActions].event = event;
626: actions[numActions].cookie = eventRegLog->eventInfo[event].cookie;
627: if (o1) actions[numActions].id1 = o1->id; else actions[numActions].id1 = -1;
628: if (o2) actions[numActions].id2 = o2->id; else actions[numActions].id2 = -1;
629: if (o3) actions[numActions].id3 = o3->id; else actions[numActions].id3 = -1;
630: actions[numActions].flops = _TotalFlops;
631: PetscTrSpace(&actions[numActions].mem, PETSC_NULL, &actions[numActions].maxmem);
632: numActions++;
633: }
634: /* Check for double counting */
635: eventPerfLog->eventInfo[event].depth--;
636: if (eventPerfLog->eventInfo[event].depth > 0) {
637: return(0);
638: } else if (eventPerfLog->eventInfo[event].depth < 0) {
639: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
640: }
641: /* Log the performance info */
642: eventPerfLog->eventInfo[event].count++;
643: eventPerfLog->eventInfo[event].time += curTime;
644: eventPerfLog->eventInfo[event].flops += _TotalFlops;
645: eventPerfLog->eventInfo[event].numMessages += irecv_ct + isend_ct + recv_ct + send_ct;
646: eventPerfLog->eventInfo[event].messageLength += irecv_len + isend_len + recv_len + send_len;
647: eventPerfLog->eventInfo[event].numReductions += allreduce_ct;
648: return(0);
649: }
651: #undef __FUNCT__
653: int PetscLogEventBeginTrace(PetscEvent event, int t, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) {
654: StageLog stageLog;
655: EventRegLog eventRegLog;
656: EventPerfLog eventPerfLog;
657: PetscLogDouble cur_time;
658: int rank, stage;
659: int ierr;
662: if (tracetime == 0.0) {PetscTime(tracetime);}
664: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
665: PetscLogGetStageLog(&stageLog);
666: StageLogGetCurrent(stageLog, &stage);
667: StageLogGetEventRegLog(stageLog, &eventRegLog);
668: StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
669: /* Check for double counting */
670: eventPerfLog->eventInfo[event].depth++;
671: tracelevel++;
672: if (eventPerfLog->eventInfo[event].depth > 1) return(0);
673: /* Log performance info */
674: PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
675: tracespace[2*tracelevel] = 0;
676: PetscTime(cur_time);
677: fprintf(tracefile, "%s[%d] %g Event begin: %sn", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
678: fflush(tracefile);
680: return(0);
681: }
683: #undef __FUNCT__
685: int PetscLogEventEndTrace(PetscEvent event,int t,PetscObject o1,PetscObject o2,PetscObject o3,PetscObject o4) {
686: StageLog stageLog;
687: EventRegLog eventRegLog;
688: EventPerfLog eventPerfLog;
689: PetscLogDouble cur_time;
690: int rank, stage;
691: int ierr;
694: tracelevel--;
695: MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
696: PetscLogGetStageLog(&stageLog);
697: StageLogGetCurrent(stageLog, &stage);
698: StageLogGetEventRegLog(stageLog, &eventRegLog);
699: StageLogGetEventPerfLog(stageLog, stage, &eventPerfLog);
700: /* Check for double counting */
701: eventPerfLog->eventInfo[event].depth--;
702: if (eventPerfLog->eventInfo[event].depth > 0) {
703: return(0);
704: } else if (eventPerfLog->eventInfo[event].depth < 0 || tracelevel < 0) {
705: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Logging event had unbalanced begin/end pairs");
706: }
707: /* Log performance info */
708: PetscStrncpy(tracespace, traceblanks, 2*tracelevel);
709: tracespace[2*tracelevel] = 0;
710: PetscTime(cur_time);
711: fprintf(tracefile, "%s[%d] %g Event end: %sn", tracespace, rank, cur_time-tracetime, eventRegLog->eventInfo[event].name);
712: fflush(tracefile);
713: return(0);
714: }