1 /* Ergo, version 3.8, a program for linear scaling electronic structure 2 * calculations. 3 * Copyright (C) 2019 Elias Rudberg, Emanuel H. Rubensson, Pawel Salek, 4 * and Anastasia Kruchinina. 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * Primary academic reference: 20 * Ergo: An open-source program for linear-scaling electronic structure 21 * calculations, 22 * Elias Rudberg, Emanuel H. Rubensson, Pawel Salek, and Anastasia 23 * Kruchinina, 24 * SoftwareX 7, 107 (2018), 25 * <http://dx.doi.org/10.1016/j.softx.2018.03.005> 26 * 27 * For further information about Ergo, see <http://www.ergoscf.org>. 28 */ 29 30 /** @file matInclude.cc 31 32 \brief Some utilities related to hierarchical matrix library. 33 */ 34 35 #include <sys/time.h> 36 #include <sys/types.h> 37 #include <unistd.h> 38 #include <stdexcept> 39 #include <cstring> 40 #include <cstdio> 41 42 #include "matInclude.h" 43 44 namespace mat { 45 46 #ifdef _OPENMP 47 unsigned int Params::nProcs = 0; 48 unsigned int Params::matrixParallelLevel = 0; 49 #endif 50 51 getNormType(const char * normStr)52 normType getNormType(const char* normStr) { 53 if ( strcmp(normStr, "eucl") == 0) 54 return mat::euclNorm; 55 if ( strcmp(normStr, "frob") == 0) 56 return mat::frobNorm; 57 if ( strcmp(normStr, "mixed") == 0) 58 return mat::mixedNorm; 59 throw "Error in mat::getNormType: Unknown norm type string."; 60 } 61 getNormTypeString(normType nType)62 std::string getNormTypeString(normType nType) { 63 switch(nType) { 64 case mat::euclNorm: return "eucl"; 65 case mat::frobNorm: return "frob"; 66 case mat::mixedNorm: return "mixed"; 67 } 68 throw "Error in mat::getNormTypeString: Unknown norm type."; 69 } 70 71 72 // Class "Time" implementation starts here! 73 get_wall_seconds()74 double Time::get_wall_seconds() { 75 struct timeval tv; 76 if(gettimeofday(&tv, NULL) != 0) 77 throw std::runtime_error("Error in get_wall_seconds(), in gettimeofday()."); 78 double seconds = tv.tv_sec + (double)tv.tv_usec / 1000000; 79 return seconds; 80 } 81 Time()82 Time::Time():ticTime(0) { } 83 tic()84 void Time::tic() { 85 ticTime = get_wall_seconds(); 86 } 87 toc()88 float Time::toc() { 89 double returnValue = get_wall_seconds() - ticTime; 90 return (float)returnValue; 91 } 92 93 94 // Class "MemUsage" implementation starts here! 95 getNumberFromBuffer(const char * buffer,const char * s)96 int MemUsage::getNumberFromBuffer(const char* buffer, const char* s) { 97 const char* p = buffer; 98 int slen = strlen(s); 99 while(1) { 100 if(*p == '\0') 101 return -11; 102 /* now p points to the beginning of a new line. */ 103 if(memcmp(p, s, slen) == 0) 104 { 105 int number; 106 /* string found! */ 107 /* skip until blank or tab */ 108 while(*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 109 p++; 110 /* skip blanks and tabs */ 111 while(*p == ' ' || *p == '\t') 112 p++; 113 /* get number */ 114 number = atoi(p); 115 /* skip until blank or tab */ 116 while(*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') 117 p++; 118 /* skip blanks and tabs */ 119 while(*p == ' ' || *p == '\t') 120 p++; 121 /* now p should point to "kB" */ 122 if(memcmp(p, "kB", 2) != 0) 123 return -22; 124 return number; 125 } 126 /* skip to next line */ 127 while(*p != '\n' && *p != '\0') 128 p++; 129 p++; 130 } 131 return -33; 132 } 133 getMemUsage(Values & values)134 void MemUsage::getMemUsage(Values & values) { 135 char fileName[888]; 136 const size_t PROCFILESIZE = 8888; 137 char buffer[PROCFILESIZE]; 138 values.virt = 0; 139 values.res = 0; 140 values.peak = 0; 141 int pid = getpid(); 142 sprintf(fileName, "/proc/%i/status", pid); 143 memset(buffer, 0, PROCFILESIZE); 144 FILE* f = fopen(fileName, "rt"); 145 // Elias note 2011-01-19: Earlier an exception was thown here, but now we just return with zero result, to make it work on Mac. 146 if(f == NULL) 147 return; 148 size_t noOfBytesRead = fread(buffer, 1, PROCFILESIZE, f); 149 fclose(f); 150 if(noOfBytesRead <= 0) 151 throw std::runtime_error("Error reading proc status file to get mem usage."); 152 if(noOfBytesRead >= PROCFILESIZE) 153 throw std::runtime_error("Error reading proc status file to get mem usage: (noOfBytesRead >= PROCFILESIZE)."); 154 int VmSize_kB = getNumberFromBuffer(buffer, "VmSize:"); 155 int VmRSS_kB = getNumberFromBuffer(buffer, "VmRSS:"); 156 int VmPeak_kB = getNumberFromBuffer(buffer, "VmPeak:"); 157 if(VmSize_kB <= 0 || VmRSS_kB <= 0) 158 throw std::runtime_error("error getting VmSize_kB or VmRSS_kB."); 159 values.virt = (float)VmSize_kB / 1000000; 160 values.res = (float)VmRSS_kB / 1000000; 161 if(VmPeak_kB > 0) 162 values.peak = (float)VmPeak_kB / 1000000; 163 else 164 values.peak = 0; 165 } 166 167 } // end namespace mat 168