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