1 #define PETSC_DLL 2 3 #include "petsc.h" /*I "petsc.h" I*/ 4 #include "petscsys.h" 5 #include "petscfix.h" 6 #if defined(PETSC_HAVE_PWD_H) 7 #include <pwd.h> 8 #endif 9 #include <ctype.h> 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #if defined(PETSC_HAVE_UNISTD_H) 13 #include <unistd.h> 14 #endif 15 #if defined(PETSC_HAVE_STDLIB_H) 16 #include <stdlib.h> 17 #endif 18 #if defined(PETSC_HAVE_SYS_UTSNAME_H) 19 #include <sys/utsname.h> 20 #endif 21 #include <fcntl.h> 22 #include <time.h> 23 #if defined(PETSC_HAVE_SYS_SYSTEMINFO_H) 24 #include <sys/systeminfo.h> 25 #endif 26 27 /* task_info seems to be buggy plus pgcc doesn't like including this file 28 #if defined(PETSC_HAVE_TASK_INFO) 29 #include <mach/mach.h> 30 #endif 31 */ 32 33 #if defined(PETSC_HAVE_SYS_RESOURCE_H) 34 #include <sys/resource.h> 35 #endif 36 #if defined(PETSC_HAVE_SYS_PROCFS_H) 37 /* #include <sys/int_types.h> Required if using gcc on solaris 2.6 */ 38 #include <sys/procfs.h> 39 #endif 40 #if defined(PETSC_HAVE_FCNTL_H) 41 #include <fcntl.h> 42 #endif 43 44 #undef __FUNCT__ 45 #define __FUNCT__ "PetscMemoryGetCurrentUsage" 46 /*@ 47 PetscMemoryGetCurrentUsage - Returns the current resident set size (memory used) 48 for the program. 49 50 Not Collective 51 52 Output Parameter: 53 . mem - memory usage in bytes 54 55 Options Database Key: 56 . -memory_info - Print memory usage at end of run 57 . -malloc_log - Activate logging of memory usage 58 59 Level: intermediate 60 61 Notes: 62 The memory usage reported here includes all Fortran arrays 63 (that may be used in application-defined sections of code). 64 This routine thus provides a more complete picture of memory 65 usage than PetscMallocGetCurrentUsage() for codes that employ Fortran with 66 hardwired arrays. 67 68 .seealso: PetscMallocGetMaximumUsage(), PetscMemoryGetMaximumUsage(), PetscMallocGetCurrentUsage() 69 70 Concepts: resident set size 71 Concepts: memory usage 72 73 @*/ 74 PetscErrorCode PETSC_DLLEXPORT PetscMemoryGetCurrentUsage(PetscLogDouble *mem) 75 { 76 #if defined(PETSC_USE_PROCFS_FOR_SIZE) 77 FILE *file; 78 int fd; 79 char proc[PETSC_MAX_PATH_LEN]; 80 prpsinfo_t prusage; 81 #elif defined(PETSC_USE_SBREAK_FOR_SIZE) 82 long *ii = sbreak(0); 83 int fd = ii - (long*)0; 84 #elif defined(PETSC_USE_PROC_FOR_SIZE) && defined(PETSC_HAVE_GETPAGESIZE) 85 FILE *file; 86 char proc[PETSC_MAX_PATH_LEN]; 87 int mm,rss,err; 88 #elif defined(PETSC_HAVE_TASK_INFO) 89 /* task_basic_info_data_t ti; 90 unsigned int count; */ 91 /* 92 The next line defined variables that are not used; but if they 93 are not included the code crashes. Something must be wrong 94 with either the task_info() command or compiler corrupting the 95 stack. 96 */ 97 /* kern_return_t kerr; */ 98 #elif defined(PETSC_HAVE_GETRUSAGE) 99 static struct rusage temp; 100 #endif 101 102 PetscFunctionBegin; 103 #if defined(PETSC_USE_PROCFS_FOR_SIZE) 104 105 sprintf(proc,"/proc/%d",(int)getpid()); 106 if ((fd = open(proc,O_RDONLY)) == -1) { 107 SETERRQ1(PETSC_ERR_FILE_OPEN,"Unable to access system file %s to get memory usage data",file); 108 } 109 if (ioctl(fd,PIOCPSINFO,&prusage) == -1) { 110 SETERRQ1(PETSC_ERR_FILE_READ,"Unable to access system file %s to get memory usage data",file); 111 } 112 *mem = (PetscLogDouble)prusage.pr_byrssize; 113 close(fd); 114 115 #elif defined(PETSC_USE_SBREAK_FOR_SIZE) 116 117 *mem = (PetscLogDouble)(8*fd - 4294967296); /* 2^32 - upper bits */ 118 119 #elif defined(PETSC_USE_PROC_FOR_SIZE) && defined(PETSC_HAVE_GETPAGESIZE) 120 sprintf(proc,"/proc/%d/statm",(int)getpid()); 121 if (!(file = fopen(proc,"r"))) { 122 SETERRQ1(PETSC_ERR_FILE_OPEN,"Unable to access system file %s to get memory usage data",proc); 123 } 124 fscanf(file,"%d %d",&mm,&rss); 125 *mem = ((PetscLogDouble)rss) * ((PetscLogDouble)getpagesize()); 126 err = fclose(file); 127 if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file"); 128 129 #elif defined(PETSC_HAVE_TASK_INFO) 130 *mem = 0; 131 /* if ((kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&ti,&count)) != KERN_SUCCESS) SETERRQ1(PETSC_ERR_LIB,"Mach system call failed: kern_return_t ",kerr); 132 *mem = (PetscLogDouble) ti.resident_size; */ 133 134 #elif defined(PETSC_HAVE_GETRUSAGE) 135 getrusage(RUSAGE_SELF,&temp); 136 #if defined(PETSC_USE_KBYTES_FOR_SIZE) 137 *mem = 1024.0 * ((PetscLogDouble)temp.ru_maxrss); 138 #elif defined(PETSC_HAVE_GETPAGESIZE) 139 *mem = ((PetscLogDouble)getpagesize())*((PetscLogDouble)temp.ru_maxrss); 140 #else 141 *mem = 0.0; 142 #endif 143 144 #else 145 *mem = 0.0; 146 #endif 147 PetscFunctionReturn(0); 148 } 149 150 PetscTruth PetscMemoryCollectMaximumUsage = PETSC_FALSE; 151 PetscLogDouble PetscMemoryMaximumUsage = 0; 152 153 #undef __FUNCT__ 154 #define __FUNCT__ "PetscMemoryGetMaximumUsage" 155 /*@ 156 PetscMemoryGetMaximumUsage - Returns the maximum resident set size (memory used) 157 for the program. 158 159 Not Collective 160 161 Output Parameter: 162 . mem - memory usage in bytes 163 164 Options Database Key: 165 . -memory_info - Print memory usage at end of run 166 . -malloc_log - Activate logging of memory usage 167 168 Level: intermediate 169 170 Notes: 171 The memory usage reported here includes all Fortran arrays 172 (that may be used in application-defined sections of code). 173 This routine thus provides a more complete picture of memory 174 usage than PetscMallocGetCurrentUsage() for codes that employ Fortran with 175 hardwired arrays. 176 177 .seealso: PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), PetscMallocGetCurrentUsage(), 178 PetscMemorySetGetMaximumUsage() 179 180 Concepts: resident set size 181 Concepts: memory usage 182 183 @*/ 184 PetscErrorCode PETSC_DLLEXPORT PetscMemoryGetMaximumUsage(PetscLogDouble *mem) 185 { 186 PetscFunctionBegin; 187 if (!PetscMemoryCollectMaximumUsage) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"To use this function you must first call PetscMemorySetGetMaximumUsage()"); 188 *mem = PetscMemoryMaximumUsage; 189 PetscFunctionReturn(0); 190 } 191 192 #undef __FUNCT__ 193 #define __FUNCT__ "PetscMemorySetGetMaximumUsage" 194 /*@C 195 PetscMemorySetGetMaximumUsage - Tells PETSc to monitor the maximum memory usage so that 196 PetscMemoryGetMaximumUsage() will work. 197 198 Not Collective 199 200 Options Database Key: 201 . -memory_info - Print memory usage at end of run 202 . -malloc_log - Activate logging of memory usage 203 204 Level: intermediate 205 206 .seealso: PetscMallocGetMaximumUsage(), PetscMemoryGetCurrentUsage(), PetscMallocGetCurrentUsage(), 207 PetscMemoryGetMaximumUsage() 208 209 Concepts: resident set size 210 Concepts: memory usage 211 212 @*/ 213 PetscErrorCode PETSC_DLLEXPORT PetscMemorySetGetMaximumUsage(void) 214 { 215 PetscFunctionBegin; 216 PetscMemoryCollectMaximumUsage = PETSC_TRUE; 217 PetscFunctionReturn(0); 218 } 219