1 static char help[] = "Tests several PetscLogHandler implementations.\n\n";
2
3 #include <petscsys.h>
4
5 /* Create a phony perfstubs implementation for testing.
6
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)
10
ps_tool_initialize(void)11 PETSC_EXTERN void ps_tool_initialize(void)
12 {
13 PetscFunctionBegin;
14 PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_initialize()\n"));
15 PetscFunctionReturnVoid();
16 }
17
ps_tool_finalize(void)18 PETSC_EXTERN void ps_tool_finalize(void)
19 {
20 PetscFunctionBegin;
21 PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_finalize()\n"));
22 PetscFunctionReturnVoid();
23 }
24
ps_tool_timer_create(const char name[])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 }
31
ps_tool_timer_start(void * arg)32 PETSC_EXTERN void *ps_tool_timer_start(void *arg)
33 {
34 const char *name = (const char *)arg;
35
36 PetscFunctionBegin;
37 PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_start() [%s]\n", name));
38 PetscFunctionReturn(NULL);
39 }
40
ps_tool_timer_stop(void * arg)41 PETSC_EXTERN void *ps_tool_timer_stop(void *arg)
42 {
43 const char *name = (const char *)arg;
44
45 PetscFunctionBegin;
46 PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_stop() [%s]\n", name));
47 PetscFunctionReturn(NULL);
48 }
49 #endif
50
CallEvents(PetscLogEvent event1,PetscLogEvent event2,PetscLogEvent event3)51 static PetscErrorCode CallEvents(PetscLogEvent event1, PetscLogEvent event2, PetscLogEvent event3)
52 {
53 char *data;
54
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 }
69
main(int argc,char ** argv)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;
76
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 }
95
96 for (PetscInt i = 0; i < 8; i++) {
97 PetscCall(PetscLogEventSetDof(event3, i, (PetscLogDouble)i));
98 PetscCall(PetscLogEventSetError(event3, i, (PetscLogDouble)i + 8));
99 }
100
101 PetscCall(CallEvents(event1, event2, event3));
102
103 PetscCall(PetscLogStagePush(stage1));
104 {
105 PetscCall(PetscSleep(0.1));
106 PetscCall(CallEvents(event1, event2, event3));
107 }
108 PetscCall(PetscLogStagePop());
109
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));
114
115 PetscCall(PetscLogStagePush(stage2));
116 {
117 PetscCall(PetscSleep(0.3));
118 PetscCall(CallEvents(event1, event2, event3));
119
120 PetscCall(PetscLogStagePush(stage1));
121 {
122 PetscCall(PetscSleep(0.1));
123 PetscCall(CallEvents(event1, event2, event3));
124 }
125 PetscCall(PetscLogStagePop());
126
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());
141
142 PetscCall(PetscContainerDestroy(&container2));
143 PetscCall(PetscContainerDestroy(&container1));
144
145 PetscCall(PetscFinalize());
146 return 0;
147 }
148
149 /*TEST
150
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
156
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"
164
165 test:
166 suffix: 2
167 requires: defined(PETSC_USE_LOG)
168 nsize: 1
169 args: -log_trace
170
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\\)"
179
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"
187
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]"
196
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\\)"
204
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]\\)"
211
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"
219
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
229
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
235
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
243
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
251
252 TEST*/
253