1 const char help[] = "How to create a log handler using legacy callbacks"; 2 3 #include <petscsys.h> 4 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. */ 9 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) 18 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}; 23 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 } 36 37 static PetscErrorCode MyEventEndHandler(PetscLogEvent event, int _unused, PetscObject o1, PetscObject o2, PetscObject o3, PetscObject o4) 38 { 39 const char *name; 40 41 PetscFunctionBegin; 42 PetscCall(PetscLogEventGetName(event, &name)); 43 PrintData("event name: %s\n", name); 44 PetscFunctionReturn(PETSC_SUCCESS); 45 } 46 47 static PetscErrorCode MyObjectCreateHandler(PetscObject o) 48 { 49 const char *obj_class; 50 51 PetscCall(PetscObjectGetClassName(o, &obj_class)); 52 PetscFunctionBegin; 53 PrintData("object class: %s\n", obj_class); 54 PetscFunctionReturn(PETSC_SUCCESS); 55 } 56 57 static PetscErrorCode MyObjectDestroyHandler(PetscObject o) 58 { 59 const char *obj_class; 60 const char *name; 61 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 } 68 69 int main(int argc, char **argv) 70 { 71 PetscLogEvent event; 72 PetscLogStage stage; 73 PetscContainer o1, o2, o3, o4; 74 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 } 98 99 /*TEST 100 101 test: 102 suffix: 0 103 requires: defined(PETSC_USE_LOG) 104 filter: sed -E "s/:[^:]+:/:time_removed:/g" 105 106 TEST*/ 107