xref: /petsc/src/dm/impls/plex/tests/ex35.c (revision 31d78bcd2b98084dc1368b20eb1129c8b9fb39fe) !
1 static char help[] = "Exhaustive memory tracking for DMPlex.\n\n\n";
2 
3 #include <petscdmplex.h>
4 
EstimateMemory(DM dm,PetscLogDouble * est)5 static PetscErrorCode EstimateMemory(DM dm, PetscLogDouble *est)
6 {
7   DMLabel  marker;
8   PetscInt cdim, depth, d, pStart, pEnd, p, Nd[4] = {0, 0, 0, 0}, lsize = 0, rmem = 0, imem = 0;
9   PetscInt coneSecMem = 0, coneMem = 0, supportSecMem = 0, supportMem = 0, labelMem = 0;
10 
11   PetscFunctionBeginUser;
12   PetscCall(PetscPrintf(PETSC_COMM_SELF, "Memory Estimates\n"));
13   PetscCall(DMGetCoordinateDim(dm, &cdim));
14   PetscCall(DMPlexGetDepth(dm, &depth));
15   PetscCall(DMPlexGetChart(dm, &pStart, &pEnd));
16   for (d = 0; d <= depth; ++d) {
17     PetscInt start, end;
18 
19     PetscCall(DMPlexGetDepthStratum(dm, d, &start, &end));
20     Nd[d] = end - start;
21   }
22   /* Coordinates: 3 Nv reals + 2*Nv + 2*Nv ints */
23   rmem += cdim * Nd[0];
24   imem += 2 * Nd[0] + 2 * Nd[0];
25   PetscCall(PetscPrintf(PETSC_COMM_SELF, "  Coordinate mem:  %" PetscInt_FMT " %" PetscInt_FMT "\n", (PetscInt)(cdim * Nd[0] * sizeof(PetscReal)), (PetscInt)(4 * Nd[0] * sizeof(PetscInt))));
26   /* Depth:       Nc+Nf+Ne+Nv ints */
27   for (d = 0; d <= depth; ++d) labelMem += Nd[d];
28   /* Cell Type:   Nc+Nf+Ne+Nv ints */
29   for (d = 0; d <= depth; ++d) labelMem += Nd[d];
30   /* Marker */
31   PetscCall(DMGetLabel(dm, "marker", &marker));
32   if (marker) PetscCall(DMLabelGetStratumSize(marker, 1, &lsize));
33   labelMem += lsize;
34   PetscCall(PetscPrintf(PETSC_COMM_SELF, "  Label mem:       %" PetscInt_FMT "\n", (PetscInt)(labelMem * sizeof(PetscInt))));
35   //imem += labelMem;
36   /* Cones and Orientations:       4 Nc + 3 Nf + 2 Ne ints + (Nc+Nf+Ne) ints no separate orientation section */
37   for (d = 0; d <= depth; ++d) coneSecMem += 2 * Nd[d];
38   for (p = pStart; p < pEnd; ++p) {
39     PetscInt csize;
40 
41     PetscCall(DMPlexGetConeSize(dm, p, &csize));
42     coneMem += csize;
43   }
44   PetscCall(PetscPrintf(PETSC_COMM_SELF, "  Cone mem:        %" PetscInt_FMT " %" PetscInt_FMT " (%" PetscInt_FMT ")\n", (PetscInt)(coneMem * sizeof(PetscInt)), (PetscInt)(coneSecMem * sizeof(PetscInt)), (PetscInt)(coneMem * sizeof(PetscInt))));
45   imem += 2 * coneMem + coneSecMem;
46   /* Supports:       4 Nc + 3 Nf + 2 Ne ints + Nc+Nf+Ne ints */
47   for (d = 0; d <= depth; ++d) supportSecMem += 2 * Nd[d];
48   for (p = pStart; p < pEnd; ++p) {
49     PetscInt ssize;
50 
51     PetscCall(DMPlexGetSupportSize(dm, p, &ssize));
52     supportMem += ssize;
53   }
54   PetscCall(PetscPrintf(PETSC_COMM_SELF, "  Support mem:     %" PetscInt_FMT " %" PetscInt_FMT "\n", (PetscInt)(supportMem * sizeof(PetscInt)), (PetscInt)(supportSecMem * sizeof(PetscInt))));
55   imem += supportMem + supportSecMem;
56   *est = ((PetscLogDouble)imem) * sizeof(PetscInt) + ((PetscLogDouble)rmem) * sizeof(PetscReal);
57   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Estimated memory %" PetscInt_FMT "\n", (PetscInt)*est));
58   PetscFunctionReturn(PETSC_SUCCESS);
59 }
60 
main(int argc,char ** argv)61 int main(int argc, char **argv)
62 {
63   DM             dm;
64   PetscBool      trace = PETSC_FALSE, checkMemory = PETSC_TRUE, auxMemory = PETSC_FALSE;
65   PetscLogDouble before, after, est                                       = 0, clean, max;
66 
67   PetscFunctionBeginUser;
68   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
69   PetscCall(PetscOptionsGetBool(NULL, NULL, "-trace", &trace, NULL));
70   PetscCall(PetscOptionsGetBool(NULL, NULL, "-check_memory", &checkMemory, NULL));
71   PetscCall(PetscOptionsGetBool(NULL, NULL, "-aux_memory", &auxMemory, NULL));
72   PetscCall(PetscMemorySetGetMaximumUsage());
73   PetscCall(PetscMallocGetCurrentUsage(&before));
74   if (trace) PetscCall(PetscMallocTraceSet(NULL, PETSC_TRUE, 5000.));
75   PetscCall(DMCreate(PETSC_COMM_WORLD, &dm));
76   PetscCall(DMSetType(dm, DMPLEX));
77   PetscCall(DMSetFromOptions(dm));
78   if (trace) PetscCall(PetscMallocTraceSet(NULL, PETSC_FALSE, 5000));
79   PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
80   PetscCall(PetscMallocGetCurrentUsage(&after));
81   PetscCall(PetscMemoryGetMaximumUsage(&max));
82   PetscCall(EstimateMemory(dm, &est));
83   PetscCall(DMDestroy(&dm));
84   PetscCall(PetscMallocGetCurrentUsage(&clean));
85   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Measured Memory\n"));
86   if (auxMemory) {
87     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Initial memory         %" PetscInt_FMT "\n  Extra memory for build %" PetscInt_FMT "\n  Memory after destroy   %" PetscInt_FMT "\n", (PetscInt)before, (PetscInt)(max - after), (PetscInt)clean));
88   }
89   if (checkMemory) {
90     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "  Memory for mesh  %" PetscInt_FMT "\n", (PetscInt)(after - before)));
91     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Discrepancy %" PetscInt_FMT "\n", (PetscInt)PetscAbsReal(after - before - est)));
92   }
93   PetscCall(PetscFinalize());
94   return 0;
95 }
96 
97 /*TEST
98   build:
99     requires: !defined(PETSC_USE_64BIT_INDICES) double !complex !defined(PETSCTEST_VALGRIND)
100 
101   # Memory checks cannot be included in tests because the allocated memory differs among environments
102   testset:
103     requires: !defined(PETSC_HAVE_THREADSAFETY)
104     args: -malloc_requested_size -dm_plex_box_faces 5,5 -check_memory 0
105     test:
106       suffix: tri
107       requires: triangle
108       args: -dm_plex_simplex 1 -dm_plex_interpolate 0
109 
110     test:
111       suffix: tri_interp
112       requires: triangle
113       args: -dm_plex_simplex 1 -dm_plex_interpolate 1
114 
115     test:
116       suffix: quad
117       args: -dm_plex_simplex 0 -dm_plex_interpolate 0
118 
119     test:
120       suffix: quad_interp
121       args: -dm_plex_simplex 0 -dm_plex_interpolate 1
122 
123   # Memory checks cannot be included in tests because the allocated memory differs among environments
124   testset:
125     requires: !defined(PETSC_HAVE_THREADSAFETY)
126     args: -malloc_requested_size -dm_plex_dim 3 -dm_plex_box_faces 5,5,5 -check_memory 0
127 
128     # Filter out label memory because tet mesher produce different surface meshes for different compilers
129     test:
130       suffix: tet
131       requires: ctetgen
132       filter: grep -v "Label mem:"
133       args: -dm_plex_simplex 1 -dm_plex_interpolate 0
134 
135     # Filter out label memory because tet mesher produce different surface meshes for different compilers
136     test:
137       suffix: tet_interp
138       requires: ctetgen
139       filter: grep -v "Label mem:"
140       args: -dm_plex_simplex 1 -dm_plex_interpolate 1
141 
142     test:
143       suffix: hex
144       args: -dm_plex_simplex 0 -dm_plex_interpolate 0
145 
146     test:
147       suffix: hex_interp
148       args: -dm_plex_simplex 0 -dm_plex_interpolate 1
149 TEST*/
150