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 utilities.h
31 
32     @brief Basic OS access utilities.
33 
34     @author: Elias Rudberg <em>responsible</em>
35 */
36 
37 #ifndef UTILITIES_HEADER
38 #define UTILITIES_HEADER
39 
40 
41 #include <time.h>
42 #include <sys/time.h>
43 #include <sys/resource.h>
44 
45 
46 #define MAX_HOST_NAME_LEN 100
47 
48 typedef struct
49 {
50   char s[MAX_HOST_NAME_LEN];
51 } host_name_struct;
52 
53 #define MAX_WORKING_DIRECTORY_LEN 800
54 
55 typedef struct
56 {
57   char s[MAX_WORKING_DIRECTORY_LEN];
58 } working_directory_struct;
59 
60 void get_host_name(host_name_struct* result);
61 
62 void get_working_directory(working_directory_struct* result);
63 
64 int get_memory_usage_by_ps(double* virtualMemoryGigaBytes, double* residentMemoryGigaBytes);
65 
66 int get_memory_usage_by_procfile(double* virtualMemGigaBytes,
67 					  double* residentMemGigaBytes,
68 					  double* virtualMemPeakGigaBytes);
69 
70 int generate_unique_random_filename(char* result, unsigned n);
71 
72 long int get_file_size(const char* fileName);
73 
74 #include <stdexcept>
75 #include "output.h"
76 #include "realtype.h"
77 namespace Util {
78   /** Time-measuring class. Measures the time between the
79       construction of the object and the call of the print method. */
80   class TimeMeter {
81   private:
82     double startTimeCPU_sys;
83     double startTimeCPU_usr;
84     double startTimeWall;
85   public:
get_start_time_wall_seconds()86     double get_start_time_wall_seconds() const {
87       return startTimeWall;
88     }
get_wall_seconds()89     static double get_wall_seconds() {
90       struct timeval tv;
91       if(gettimeofday(&tv, NULL) != 0)
92         throw std::runtime_error("Error in get_wall_seconds(), in gettimeofday().");
93       double seconds = tv.tv_sec + (double)tv.tv_usec / 1000000;
94       return seconds;
95     }
get_current_cpu_times(double & seconds_usr,double & seconds_sys)96     static void get_current_cpu_times(double & seconds_usr, double & seconds_sys) {
97       struct rusage usage;
98       if(getrusage (RUSAGE_SELF, &usage) != 0)
99 	throw std::runtime_error("Error in get_current_cpu_times(), in getrusage().");
100       seconds_usr = usage.ru_utime.tv_sec + (double)usage.ru_utime.tv_usec / 1000000;
101       seconds_sys = usage.ru_stime.tv_sec + (double)usage.ru_stime.tv_usec / 1000000;
102     }
TimeMeter()103     TimeMeter() {
104       startTimeWall = get_wall_seconds();
105       get_current_cpu_times(startTimeCPU_usr, startTimeCPU_sys);
106     }
get_elapsed_wall_seconds()107     double get_elapsed_wall_seconds() {
108       double endTimeWall = get_wall_seconds();
109       return endTimeWall - startTimeWall;
110     }
print(int area,const char * routine)111     void print(int area, const char *routine) {
112       double endTimeWall = get_wall_seconds();
113       double secondsTakenWall = endTimeWall - startTimeWall;
114       double seconds_usr, seconds_sys;
115       get_current_cpu_times(seconds_usr, seconds_sys);
116       double secondsTakenCPU_usr = seconds_usr - startTimeCPU_usr;
117       double secondsTakenCPU_sys = seconds_sys - startTimeCPU_sys;
118       do_output(LOG_CAT_TIMINGS, area, "%s took %9.2f usr cpu s  %9.2f sys cpu s  %9.2f wall s",
119 		routine, secondsTakenCPU_usr, secondsTakenCPU_sys, secondsTakenWall);
120     }
121 
122 
123   };
124 }
125 
126 
127 #endif /* UTILITIES_HEADER */
128