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, NULL, 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.3));
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}}
155: output_file: output/empty.out
157: # flamegraph: times of PetscSleep() are designed so the flamegraph should have reproducible entries
158: test:
159: suffix: 1
160: nsize: {{1 2}}
161: requires: defined(PETSC_USE_LOG)
162: args: -log_view ::ascii_flamegraph
163: filter: sed -E "s/ [0-9]+/ time_removed/g"
165: test:
166: suffix: 2
167: requires: defined(PETSC_USE_LOG)
168: nsize: 1
169: args: -log_trace
171: # test PetscLogDump() with action and object logging
172: test:
173: suffix: 3
174: nsize: 1
175: requires: defined(PETSC_USE_LOG)
176: args: -log_include_actions -log_include_objects -log_all
177: temporaries: Log.0
178: filter: cat Log.0 | grep "\\(Actions accomplished\\|Objects created\\|Name\\|Info\\)"
180: # -log_sync is not necessary for csv output, this is just a convenient test to add sync testing to
181: test:
182: suffix: 4
183: nsize: 2
184: requires: defined(PETSC_USE_LOG)
185: args: -log_view ::ascii_csv -log_sync
186: filter: grep "Event[123]" | grep -v "PCMPI"
188: # we don't guarantee clog2print is available, so we just verify that our events are in the output file
189: test:
190: suffix: 5
191: nsize: 1
192: requires: defined(PETSC_USE_LOG) defined(PETSC_HAVE_MPE)
193: args: -log_mpe ex30_mpe
194: temporaries: ex30_mpe.clog2
195: filter: strings ex30_mpe.clog2 | grep "Event[123]"
197: # we don't have tau as a dependency, so we test a dummy perfstubs tool
198: test:
199: suffix: 6
200: nsize: 1
201: requires: tau_perfstubs linux dlfcn_h defined(PETSC_USE_LOG) defined(PETSC_USE_SHARED_LIBRARIES)
202: args: -log_perfstubs
203: filter: grep "\\(Main Stage\\|Event1\\|Event2\\|Event3\\|Stage1\\|Stage2\\)"
205: test:
206: suffix: 7
207: nsize: 1
208: requires: defined(PETSC_USE_LOG)
209: args: -log_view ::ascii_info_detail -log_handler_default_use_threadsafe_events
210: filter: grep "Event[123]" | grep "\\(Main Stage\\|Stage[123]\\)"
212: # test the sync warning
213: test:
214: suffix: 8
215: nsize: 2
216: requires: defined(PETSC_USE_LOG)
217: args: -log_view -log_sync
218: filter: grep "This program was run with logging synchronization"
220: # test -log_trace with an output file
221: test:
222: suffix: 9
223: requires: defined(PETSC_USE_LOG)
224: nsize: 1
225: output_file: output/ex30_2.out
226: args: -log_trace trace.log
227: temporaries: trace.log
228: filter: cat trace.log.0
230: # test -log_nvtx
231: test:
232: suffix: 10
233: requires: cuda defined(PETSC_USE_LOG)
234: args: -device_enable eager -log_nvtx -info :loghandler
236: # test multiple view: default listed first
237: test:
238: suffix: 11
239: requires: defined(PETSC_USE_LOG)
240: output_file: output/empty.out
241: temporaries: default.log flamegraph.log
242: args: -log_view :default.log,:flamegraph.log:ascii_flamegraph
244: # test multiple view: default listed second
245: test:
246: suffix: 12
247: requires: defined(PETSC_USE_LOG)
248: output_file: output/empty.out
249: temporaries: default.log flamegraph.log
250: args: -log_view :flamegraph.log:ascii_flamegraph,:default.log
252: TEST*/