xref: /petsc/src/sys/tests/ex30.c (revision 57d508425293f0bb93f59574d14951d8faac9af8)
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 
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 
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 
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 
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 
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 
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 
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