Actual source code: ex6.c
1: const char help[] = "How to create a log handler using legacy callbacks";
3: #include <petscsys.h>
5: /* Log handlers that use the legacy callbacks have no context pointer,
6: but they can access global logging information. If your log handler only
7: needs to interact with the arguments to the callback functions and global
8: data structures, the legacy callbacks can be used. */
10: #define PrintData(format_string, ...) \
11: do { \
12: PetscMPIInt rank; \
13: PetscLogDouble time; \
14: PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); \
15: PetscCall(PetscTime(&time)); \
16: PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d:%g:%-22s] " format_string, rank, time, PETSC_FUNCTION_NAME, __VA_ARGS__)); \
17: } while (0)
19: static PetscErrorCode MyEventBeginHandler(PetscLogEvent event, int _unused, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
20: {
21: const char *name;
22: PetscObject objs[] = {o1, o2, o3, o4};
24: PetscFunctionBegin;
25: PetscCall(PetscLogEventGetName(event, &name));
26: PrintData("event name: %s\n", name);
27: for (int i = 0; i < 4; i++) {
28: if (objs[i]) {
29: const char *obj_name;
30: PetscCall(PetscObjectGetName(objs[i], &obj_name));
31: PrintData(" associated object name: %s\n", obj_name);
32: }
33: }
34: PetscFunctionReturn(PETSC_SUCCESS);
35: }
37: static PetscErrorCode MyEventEndHandler(PetscLogEvent event, int _unused, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4)
38: {
39: const char *name;
41: PetscFunctionBegin;
42: PetscCall(PetscLogEventGetName(event, &name));
43: PrintData("event name: %s\n", name);
44: PetscFunctionReturn(PETSC_SUCCESS);
45: }
47: static PetscErrorCode MyObjectCreateHandler(PetscObject o)
48: {
49: const char *obj_class;
51: PetscCall(PetscObjectGetClassName(o, &obj_class));
52: PetscFunctionBegin;
53: PrintData("object class: %s\n", obj_class);
54: PetscFunctionReturn(PETSC_SUCCESS);
55: }
57: static PetscErrorCode MyObjectDestroyHandler(PetscObject o)
58: {
59: const char *obj_class;
60: const char *name;
62: PetscCall(PetscObjectGetClassName(o, &obj_class));
63: PetscCall(PetscObjectGetName(o, &name));
64: PetscFunctionBegin;
65: PrintData("object type: %s, name: %s\n", obj_class, name);
66: PetscFunctionReturn(PETSC_SUCCESS);
67: }
69: int main(int argc, char **argv)
70: {
71: PetscLogEvent event;
72: PetscLogStage stage;
73: PetscContainer o1, o2, o3, o4;
75: PetscCall(PetscInitialize(&argc, &argv, NULL, help));
76: PetscCall(PetscLogLegacyCallbacksBegin(MyEventBeginHandler, MyEventEndHandler, MyObjectCreateHandler, MyObjectDestroyHandler));
77: PetscCall(PetscLogStageRegister("User stage", &stage));
78: PetscCall(PetscLogEventRegister("User class", PETSC_CONTAINER_CLASSID, &event));
79: PetscCall(PetscLogStagePush(stage));
80: PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &o1));
81: PetscCall(PetscObjectSetName((PetscObject)o1, "Container 1"));
82: PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &o2));
83: PetscCall(PetscObjectSetName((PetscObject)o2, "Container 2"));
84: PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &o3));
85: PetscCall(PetscObjectSetName((PetscObject)o3, "Container 3"));
86: PetscCall(PetscContainerCreate(PETSC_COMM_WORLD, &o4));
87: PetscCall(PetscObjectSetName((PetscObject)o4, "Container 4"));
88: PetscCall(PetscLogEventBegin(event, o1, o2, o3, o4));
89: PetscCall(PetscLogEventEnd(event, o1, o2, o3, o4));
90: PetscCall(PetscContainerDestroy(&o1));
91: PetscCall(PetscContainerDestroy(&o2));
92: PetscCall(PetscContainerDestroy(&o3));
93: PetscCall(PetscContainerDestroy(&o4));
94: PetscCall(PetscLogStagePop());
95: PetscCall(PetscFinalize());
96: return 0;
97: }
99: /*TEST
101: test:
102: suffix: 0
103: requires: defined(PETSC_USE_LOG)
104: filter: sed -E "s/:[^:]+:/:time_removed:/g"
106: TEST*/