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 output.cc
31
32 @brief Functionality for writing output messages to a text file.
33
34 @author: Elias Rudberg <em>responsible</em>
35 */
36
37 #include <time.h>
38 #include <stdarg.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include "output.h"
42 #include "utilities.h"
43
44 static int global_memory_usage_output_flag = 0; /* mem output disabled by default */
45
46 /* We choose to have output disabled by default, until enable_output() is called, to make sure output is disabled on worker processes when CHT is used. */
47 static int global_output_enabled_flag = 0; /* output disabled by default */
48
49 static int use_printf = 0; /* use printf */
50
51 /* general output routine */
52 void
do_output(int logCategory,int logArea,const char * format,...)53 do_output(int logCategory, int logArea, const char* format, ...)
54 {
55 va_list a;
56 va_start(a, format);
57 if(use_printf)
58 do_voutput_printf(logCategory, logArea, format, a);
59 else
60 do_voutput(logCategory, logArea, format, a);
61 va_end(a);
62 }
63
64 /* output in stdout using printf */
65 void
enable_printf_output()66 enable_printf_output()
67 {
68 global_output_enabled_flag = 1;
69 use_printf = 1;
70
71 //global_memory_usage_output_flag = 1;
72 }
73
74
75 int
do_voutput_printf(int logCategory,int logArea,const char * format,va_list a)76 do_voutput_printf(int logCategory, int logArea, const char* format, va_list a)
77 {
78 if(global_output_enabled_flag == 0)
79 return 0; // Output is disabled; do nothing, just return.
80
81 char ss[8888]; /* FIXME: Do something nicer here. */
82 int r;
83
84 memset(ss, 0, sizeof(ss));
85 r = vsnprintf(ss, sizeof(ss), format, a);
86
87 printf("%s\n", ss);
88
89 return r;
90 }
91
92
93 int
do_voutput(int logCategory,int logArea,const char * format,va_list a)94 do_voutput(int logCategory, int logArea, const char* format, va_list a)
95 {
96 if(global_output_enabled_flag == 0)
97 return 0; // Output is disabled; do nothing, just return.
98
99 char ss[8888]; /* FIXME: Do something nicer here. */
100 int r;
101
102 memset(ss, 0, sizeof(ss));
103
104 /* The output line should begin with two characters
105 specifying the log category, followed by two characters
106 specifying the log area. */
107 switch(logCategory)
108 {
109 case LOG_CAT_UNDEFINED: strcat(ss, " "); break;
110 case LOG_CAT_ERROR: strcat(ss, "ER"); break;
111 case LOG_CAT_WARNING: strcat(ss, "WA"); break;
112 case LOG_CAT_INFO: strcat(ss, "IN"); break;
113 case LOG_CAT_EXTRAINFO: strcat(ss, "EX"); break;
114 case LOG_CAT_RESULTS: strcat(ss, "RE"); break;
115 case LOG_CAT_TIMINGS: strcat(ss, "TI"); break;
116 case LOG_CAT_MEMUSAGE: strcat(ss, "ME"); break;
117 default: strcat(ss, " "); break;
118 }
119 switch(logArea)
120 {
121 case LOG_AREA_UNDEFINED: strcat(ss, " "); break;
122 case LOG_AREA_MAIN: strcat(ss, "MA"); break;
123 case LOG_AREA_SCF: strcat(ss, "SC"); break;
124 case LOG_AREA_LR: strcat(ss, "LR"); break;
125 case LOG_AREA_INTEGRALS: strcat(ss, "IN"); break;
126 case LOG_AREA_DENSFROMF: strcat(ss, "DE"); break;
127 case LOG_AREA_DFT : strcat(ss, "DF"); break;
128 case LOG_AREA_LOWLEVEL: strcat(ss, "LO"); break;
129 case LOG_AREA_CI: strcat(ss, "CI"); break;
130 case LOG_AREA_ED: strcat(ss, "ED"); break;
131 case LOG_AREA_GS: strcat(ss, "GS"); break;
132 default: strcat(ss, " "); break;
133 }
134
135 strcat(ss, " ");
136
137 r = vsnprintf(ss+5, sizeof(ss)-5, format, a);
138
139 #if 0
140 /* This needs to be protected with mutex. */
141 if(global_output_file == NULL)
142 global_output_file = fopen("ergoscf.out", "wt");
143 fprintf(global_output_file, "%s\n", ss);
144 fflush(global_output_file);
145 #else
146 /* append to output file */
147 {
148 FILE *output_file = fopen("ergoscf.out", "at");
149 fprintf(output_file, "%s\n", ss);
150 fclose(output_file);
151 }
152 #endif
153 return r;
154 }
155
156
157
158 void
do_output_time(int logCategory,int logArea,const char * s)159 do_output_time(int logCategory, int logArea, const char* s)
160 {
161 int len;
162 char timeString[88];
163 char ss[222];
164 time_t rawtime;
165 time(&rawtime);
166 strcpy(timeString, ctime(&rawtime));
167 len = (int)strlen(timeString);
168 if(timeString[len-1] == '\n')
169 timeString[len-1] = '\0';
170 sprintf(ss, "%s %s", s, timeString);
171 do_output(logCategory, logArea, ss);
172 }
173
174 void
enable_memory_usage_output()175 enable_memory_usage_output()
176 {
177 global_memory_usage_output_flag = 1;
178 }
179
180 void
enable_output()181 enable_output()
182 {
183 global_output_enabled_flag = 1;
184 }
185
output_current_memory_usage(int logArea,const char * contextString)186 void output_current_memory_usage(int logArea, const char* contextString)
187 {
188 double virt, res, virtPeak;
189
190 if(global_memory_usage_output_flag == 0)
191 return;
192
193 if(get_memory_usage_by_procfile(&virt, &res, &virtPeak) != 0)
194 {
195 /* error getting memory usage */
196 do_output(LOG_CAT_MEMUSAGE, logArea, "memory usage at '%s': virt ???? res ???? v peak ????",
197 contextString);
198 }
199 else
200 {
201 do_output(LOG_CAT_MEMUSAGE, logArea, "memory usage at '%s': virt %6.3f G res %6.3f G v peak %6.3f G",
202 contextString, virt, res, virtPeak);
203 }
204 }
205
206
207