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