xref: /petsc/src/sys/tests/ex30.c (revision dbff2e812d3f1975f2fc386c980b1b5f65f538ff)
1 
2 static char help[] = "Tests several PetscLogHandler implementations.\n\n";
3 
4 #include <petscsys.h>
5 
6 /* Create a phony perfstubs implementation for testing.
7 
8    The dynamic loading in perfstubs is only enabled with the following flags,
9    so we only try to export these functions if they are present */
10 #if defined(__linux__) && PetscDefined(HAVE_DLFCN_H)
11 
12 PETSC_EXTERN void ps_tool_initialize(void)
13 {
14   PetscFunctionBegin;
15   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_initialize()\n"));
16   PetscFunctionReturnVoid();
17 }
18 
19 PETSC_EXTERN void ps_tool_finalize(void)
20 {
21   PetscFunctionBegin;
22   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_finalize()\n"));
23   PetscFunctionReturnVoid();
24 }
25 
26 PETSC_EXTERN void *ps_tool_timer_create(const char name[])
27 {
28   PetscFunctionBegin;
29   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_create(\"%s\")\n", name));
30   PetscFunctionReturn((void *)name);
31 }
32 
33 PETSC_EXTERN void *ps_tool_timer_start(void *arg)
34 {
35   const char *name = (const char *)arg;
36 
37   PetscFunctionBegin;
38   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_start() [%s]\n", name));
39   PetscFunctionReturn(NULL);
40 }
41 
42 PETSC_EXTERN void *ps_tool_timer_stop(void *arg)
43 {
44   const char *name = (const char *)arg;
45 
46   PetscFunctionBegin;
47   PetscCallContinue(PetscPrintf(PETSC_COMM_SELF, "ps_tool_timer_stop() [%s]\n", name));
48   PetscFunctionReturn(NULL);
49 }
50 #endif
51 
52 static PetscErrorCode CallEvents(PetscLogEvent event1, PetscLogEvent event2, PetscLogEvent event3)
53 {
54   char *data;
55 
56   PetscFunctionBegin;
57   PetscCall(PetscLogEventBegin(event1, NULL, NULL, NULL, NULL));
58   PetscCall(PetscSleep(0.05));
59   PetscCall(PetscLogEventBegin(event2, NULL, NULL, NULL, NULL));
60   PetscCall(PetscSleep(0.1));
61   PetscCall(PetscLogEventBegin(event3, NULL, NULL, NULL, NULL));
62   PetscCall(PetscCalloc1(1048576, &data));
63   PetscCall(PetscFree(data));
64   PetscCall(PetscSleep(0.15));
65   PetscCall(PetscLogEventEnd(event3, NULL, NULL, NULL, NULL));
66   PetscCall(PetscLogEventEnd(event2, NULL, NULL, NULL, NULL));
67   PetscCall(PetscLogEventEnd(event1, NULL, NULL, NULL, NULL));
68   PetscFunctionReturn(PETSC_SUCCESS);
69 }
70 
71 int main(int argc, char **argv)
72 {
73   PetscLogStage  stage1, stage2, stage3 = -1;
74   PetscLogEvent  event1, event2, event3;
75   PetscMPIInt    rank;
76   PetscContainer container1, container2;
77 
78   PetscFunctionBeginUser;
79   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
80   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
81   if (rank) {
82     PetscCall(PetscLogEventRegister("Event3", 0, &event3));
83     PetscCall(PetscLogEventRegister("Event2", 0, &event2));
84     PetscCall(PetscLogEventRegister("Event1", PETSC_CONTAINER_CLASSID, &event1));
85     PetscCall(PetscLogStageRegister("Stage2", &stage2));
86     PetscCall(PetscLogStageRegister("Stage1", &stage1));
87     PetscCall(PetscLogStageRegister("Stage3", &stage3));
88     (void)stage3; // stage3 intentionally not used
89   } else {
90     PetscCall(PetscLogEventRegister("Event2", 0, &event2));
91     PetscCall(PetscLogEventRegister("Event1", PETSC_CONTAINER_CLASSID, &event1));
92     PetscCall(PetscLogEventRegister("Event3", 0, &event3));
93     PetscCall(PetscLogStageRegister("Stage1", &stage1));
94     PetscCall(PetscLogStageRegister("Stage2", &stage2));
95   }
96 
97   for (PetscInt i = 0; i < 8; i++) {
98     PetscCall(PetscLogEventSetDof(event3, i, (PetscLogDouble)i));
99     PetscCall(PetscLogEventSetError(event3, i, (PetscLogDouble)i + 8));
100   }
101 
102   PetscCall(CallEvents(event1, event2, event3));
103 
104   PetscCall(PetscLogStagePush(stage1));
105   {
106     PetscCall(PetscSleep(0.1));
107     PetscCall(CallEvents(event1, event2, event3));
108   }
109   PetscCall(PetscLogStagePop());
110 
111   PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &container1));
112   PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &container2));
113   PetscCall(PetscObjectSetName((PetscObject)container2, "Container 2"));
114   PetscCall(PetscLogObjectState((PetscObject)container1, "Setting object state for testing purposes with %d self-referential format argument", 1));
115 
116   PetscCall(PetscLogStagePush(stage2));
117   {
118     PetscCall(PetscSleep(0.1));
119     PetscCall(CallEvents(event1, event2, event3));
120 
121     PetscCall(PetscLogStagePush(stage1));
122     {
123       PetscCall(PetscSleep(0.1));
124       PetscCall(CallEvents(event1, event2, event3));
125     }
126     PetscCall(PetscLogStagePop());
127 
128     PetscCall(PetscLogEventSync(event1, PETSC_COMM_WORLD));
129     PetscCall(PetscLogEventBegin(event1, container1, container2, NULL, NULL));
130     {
131       PetscCall(PetscSleep(0.1));
132       PetscCall(PetscLogStagePush(stage1));
133       {
134         PetscCall(PetscSleep(0.1));
135         PetscCall(CallEvents(event1, event2, event3));
136       }
137       PetscCall(PetscLogStagePop());
138     }
139     PetscCall(PetscLogEventEnd(event1, container1, container2, NULL, NULL));
140   }
141   PetscCall(PetscLogStagePop());
142 
143   PetscCall(PetscContainerDestroy(&container2));
144   PetscCall(PetscContainerDestroy(&container1));
145 
146   PetscCall(PetscFinalize());
147   return 0;
148 }
149 
150 /*TEST
151 
152   # smoke test: does this program run with / without PETSC_USE_LOG?
153   test:
154     suffix: 0
155     nsize: {{1 2}}
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*/
231