Actual source code: ex30.c

  1: static char help[] = "Tests several PetscLogHandler implementations.\n\n";

  3: #include <petscsys.h>

  5: /* Create a phony perfstubs implementation for testing.

  7:    The dynamic loading in perfstubs is only enabled with the following flags,
  8:    so we only try to export these functions if they are present */
  9: #if defined(__linux__) && PetscDefined(HAVE_DLFCN_H)

 11: PETSC_EXTERN void ps_tool_initialize(void)
 12: {
 13:   PetscFunctionBegin;
 14:   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_initialize()\n"));
 15:   PetscFunctionReturnVoid();
 16: }

 18: PETSC_EXTERN void ps_tool_finalize(void)
 19: {
 20:   PetscFunctionBegin;
 21:   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_finalize()\n"));
 22:   PetscFunctionReturnVoid();
 23: }

 25: PETSC_EXTERN void *ps_tool_timer_create(const char name[])
 26: {
 27:   PetscFunctionBegin;
 28:   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_create(\"%s\")\n", name));
 29:   PetscFunctionReturn((void *)name);
 30: }

 32: PETSC_EXTERN void *ps_tool_timer_start(void *arg)
 33: {
 34:   const char *name = (const char *)arg;

 36:   PetscFunctionBegin;
 37:   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_start() [%s]\n", name));
 38:   PetscFunctionReturn(NULL);
 39: }

 41: PETSC_EXTERN void *ps_tool_timer_stop(void *arg)
 42: {
 43:   const char *name = (const char *)arg;

 45:   PetscFunctionBegin;
 46:   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_stop() [%s]\n", name));
 47:   PetscFunctionReturn(NULL);
 48: }
 49: #endif

 51: static PetscErrorCode CallEvents(PetscLogEvent event1, PetscLogEvent event2, PetscLogEvent event3)
 52: {
 53:   char *data;

 55:   PetscFunctionBegin;
 56:   PetscCall(PetscLogEventBegin(event1, NULL, NULL, NULL, NULL));
 57:   PetscCall(PetscSleep(0.05));
 58:   PetscCall(PetscLogEventBegin(event2, NULL, NULL, NULL, NULL));
 59:   PetscCall(PetscSleep(0.1));
 60:   PetscCall(PetscLogEventBegin(event3, NULL, NULL, NULL, NULL));
 61:   PetscCall(PetscCalloc1(1048576, &data));
 62:   PetscCall(PetscFree(data));
 63:   PetscCall(PetscSleep(0.15));
 64:   PetscCall(PetscLogEventEnd(event3, NULL, NULL, NULL, NULL));
 65:   PetscCall(PetscLogEventEnd(event2, NULL, NULL, NULL, NULL));
 66:   PetscCall(PetscLogEventEnd(event1, NULL, NULL, NULL, NULL));
 67:   PetscFunctionReturn(PETSC_SUCCESS);
 68: }

 70: int main(int argc, char **argv)
 71: {
 72:   PetscLogStage  stage1, stage2, stage3 = -1;
 73:   PetscLogEvent  event1, event2, event3;
 74:   PetscMPIInt    rank;
 75:   PetscContainer container1, container2;

 77:   PetscFunctionBeginUser;
 78:   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
 79:   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
 80:   if (rank) {
 81:     PetscCall(PetscLogEventRegister("Event3", 0, &event3));
 82:     PetscCall(PetscLogEventRegister("Event2", 0, &event2));
 83:     PetscCall(PetscLogEventRegister("Event1", PETSC_CONTAINER_CLASSID, &event1));
 84:     PetscCall(PetscLogStageRegister("Stage2", &stage2));
 85:     PetscCall(PetscLogStageRegister("Stage1", &stage1));
 86:     PetscCall(PetscLogStageRegister("Stage3", &stage3));
 87:     (void)stage3; // stage3 intentionally not used
 88:   } else {
 89:     PetscCall(PetscLogEventRegister("Event2", 0, &event2));
 90:     PetscCall(PetscLogEventRegister("Event1", PETSC_CONTAINER_CLASSID, &event1));
 91:     PetscCall(PetscLogEventRegister("Event3", 0, &event3));
 92:     PetscCall(PetscLogStageRegister("Stage1", &stage1));
 93:     PetscCall(PetscLogStageRegister("Stage2", &stage2));
 94:   }

 96:   for (PetscInt i = 0; i < 8; i++) {
 97:     PetscCall(PetscLogEventSetDof(event3, i, (PetscLogDouble)i));
 98:     PetscCall(PetscLogEventSetError(event3, i, (PetscLogDouble)i + 8));
 99:   }

101:   PetscCall(CallEvents(event1, event2, event3));

103:   PetscCall(PetscLogStagePush(stage1));
104:   {
105:     PetscCall(PetscSleep(0.1));
106:     PetscCall(CallEvents(event1, event2, event3));
107:   }
108:   PetscCall(PetscLogStagePop());

110:   PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &container1));
111:   PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &container2));
112:   PetscCall(PetscObjectSetName((PetscObject)container2, "Container 2"));
113:   PetscCall(PetscLogObjectState((PetscObject)container1, "Setting object state for testing purposes with %d self-referential format argument", 1));

115:   PetscCall(PetscLogStagePush(stage2));
116:   {
117:     PetscCall(PetscSleep(0.1));
118:     PetscCall(CallEvents(event1, event2, event3));

120:     PetscCall(PetscLogStagePush(stage1));
121:     {
122:       PetscCall(PetscSleep(0.1));
123:       PetscCall(CallEvents(event1, event2, event3));
124:     }
125:     PetscCall(PetscLogStagePop());

127:     PetscCall(PetscLogEventSync(event1, PETSC_COMM_WORLD));
128:     PetscCall(PetscLogEventBegin(event1, container1, container2, NULL, NULL));
129:     {
130:       PetscCall(PetscSleep(0.1));
131:       PetscCall(PetscLogStagePush(stage1));
132:       {
133:         PetscCall(PetscSleep(0.1));
134:         PetscCall(CallEvents(event1, event2, event3));
135:       }
136:       PetscCall(PetscLogStagePop());
137:     }
138:     PetscCall(PetscLogEventEnd(event1, container1, container2, NULL, NULL));
139:   }
140:   PetscCall(PetscLogStagePop());

142:   PetscCall(PetscContainerDestroy(&container2));
143:   PetscCall(PetscContainerDestroy(&container1));

145:   PetscCall(PetscFinalize());
146:   return 0;
147: }

149: /*TEST

151:   # smoke test: does this program run with / without PETSC_USE_LOG?
152:   test:
153:     suffix: 0
154:     nsize: {{1 2}}

156:   # flamegraph: times of PetscSleep() are designed so the flamegraph should have reproducible entries
157:   test:
158:     suffix: 1
159:     nsize: {{1 2}}
160:     requires: defined(PETSC_USE_LOG)
161:     args: -log_view ::ascii_flamegraph
162:     filter: sed -E "s/ [0-9]+/ time_removed/g"

164:   test:
165:     suffix: 2
166:     requires: defined(PETSC_USE_LOG)
167:     nsize: 1
168:     args: -log_trace

170:   # test PetscLogDump() with action and object logging
171:   test:
172:     suffix: 3
173:     nsize: 1
174:     requires: defined(PETSC_USE_LOG)
175:     args: -log_include_actions -log_include_objects -log_all
176:     temporaries: Log.0
177:     filter: cat Log.0 | grep "\\(Actions accomplished\\|Objects created\\|Name\\|Info\\)"

179:   # -log_sync is not necessary for csv output, this is just a convenient test to add sync testing to
180:   test:
181:     suffix: 4
182:     nsize: 2
183:     requires: defined(PETSC_USE_LOG)
184:     args: -log_view ::ascii_csv -log_sync
185:     filter: grep "Event[123]" | grep -v "PCMPI"

187:   # we don't guarantee clog2print is available, so we just verify that our events are in the output file
188:   test:
189:     suffix: 5
190:     nsize: 1
191:     requires: defined(PETSC_USE_LOG) defined(PETSC_HAVE_MPE)
192:     args: -log_mpe ex30_mpe
193:     temporaries: ex30_mpe.clog2
194:     filter: strings ex30_mpe.clog2 | grep "Event[123]"

196:   # we don't have tau as a dependency, so we test a dummy perfstubs tool
197:   test:
198:     suffix: 6
199:     nsize: 1
200:     requires: tau_perfstubs linux dlfcn_h defined(PETSC_USE_LOG) defined(PETSC_USE_SHARED_LIBRARIES)
201:     args: -log_perfstubs
202:     filter: grep "\\(Main Stage\\|Event1\\|Event2\\|Event3\\|Stage1\\|Stage2\\)"

204:   test:
205:     suffix: 7
206:     nsize: 1
207:     requires: defined(PETSC_USE_LOG)
208:     args: -log_view ::ascii_info_detail -log_handler_default_use_threadsafe_events
209:     filter: grep "Event[123]" | grep "\\(Main Stage\\|Stage[123]\\)"

211:   # test the sync warning
212:   test:
213:     suffix: 8
214:     nsize: 2
215:     requires: defined(PETSC_USE_LOG)
216:     args: -log_view -log_sync
217:     filter: grep "This program was run with logging synchronization"

219:   # test -log_trace with an output file
220:   test:
221:     suffix: 9
222:     requires: defined(PETSC_USE_LOG)
223:     nsize: 1
224:     output_file: output/ex30_2.out
225:     args: -log_trace trace.log
226:     temporaries: trace.log
227:     filter: cat trace.log.0

229:   # test -log_nvtx
230:   test:
231:     suffix: 10
232:     requires: cuda defined(PETSC_USE_LOG)
233:     args: -device_enable eager -log_nvtx -info :loghandler

235:  TEST*/