JDFTx  1.1.0
Util.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman
3 
4 This file is part of JDFTx.
5 
6 JDFTx 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 JDFTx 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 JDFTx. If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19 
20 #ifndef JDFTX_CORE_UTIL_H
21 #define JDFTX_CORE_UTIL_H
22 
27 #include <core/MPIUtil.h>
28 #include <map>
29 #include <array>
30 #include <cstring>
31 #include <cstdio>
32 #include <cstdint>
33 #include <sys/time.h>
34 #include <sys/wait.h>
35 #include <unistd.h>
36 #include <execinfo.h>
37 
38 //------------- Common Initialization -----------------
39 
40 extern bool killFlag;
41 extern MPIUtil* mpiUtil;
42 extern bool mpiDebugLog;
43 void printVersionBanner();
44 void initSystem(int argc, char** argv);
45 void initSystemCmdline(int argc, char** argv, const char* description, string& inputFilename, bool& dryRun, bool& printDefaults);
46 void finalizeSystem(bool successful=true);
47 
48 //----------------- Profiling --------------------------
49 
50 double clock_us();
51 double clock_sec();
52 
59 #define TIME(title,fp,code) \
60 { double runTime = clock_us(); \
61  { code } \
62  runTime = clock_us() - runTime; \
63  fprintf(fp, "%s took %.2le s.\n", title, runTime*1e-6); \
64 }
65 
70 #ifdef ENABLE_PROFILING
71 class StopWatch
72 {
73 public:
74  StopWatch(string name);
75  void start();
76  void stop();
77  void print() const;
78 private:
79  double tPrev, Ttot, TsqTot; int nT;
80  string name;
81 };
82 #else //ENABLE_PROFILING
83 //Version which does no profiling for release versions
84 class StopWatch
85 {
86 public:
87  StopWatch(string name) {}
88  void start() {}
89  void stop() {}
90 };
91 #endif //ENABLE_PROFILING
92 
93 
94 
95 // ----------- Debugging ---------------
96 void printStack(bool detailedStackScript=false);
97 void stackTraceExit(int code);
98 int assertStackTraceExit(const char* expr, const char* function, const char* file, long line);
99 #define assert(expr) \
101  (void)((expr) ? 0 : assertStackTraceExit(#expr, __func__, __FILE__, __LINE__))
102 
103 
104 // ----------- Logging ---------------
105 extern FILE* globalLog;
106 extern FILE* nullLog;
107 void logSuspend();
108 void logResume();
109 
110 #define logPrintf(...) fprintf(globalLog, __VA_ARGS__)
111 #define logFlush() fflush(globalLog)
112 
113 #define die(...) \
115  { fprintf(globalLog, __VA_ARGS__); \
116  if(mpiUtil->isHead() && globalLog != stdout) \
117  fprintf(stderr, __VA_ARGS__); \
118  finalizeSystem(false); \
119  exit(1); \
120  }
121 
123 #define die_alone(...) \
124  { fprintf(globalLog, __VA_ARGS__); \
125  fflush(globalLog); \
126  if(mpiUtil->isHead() && globalLog != stdout) \
127  fprintf(stderr, __VA_ARGS__); \
128  if(mpiUtil->nProcesses() == 1) finalizeSystem(false); /* Safe to call only if no other process */ \
129  mpiUtil->exit(1); \
130  }
131 
132 //--------------- Citations --------------------
133 namespace Citations
134 {
135  void add(string reason, string paper);
137 
139  void print(FILE* fp=globalLog);
140 }
141 
142 
143 //--------------- Miscellaneous ------------------
144 
145 
146 #include <sys/stat.h>
148 off_t fileSize(const char *filename);
149 
151 inline uint16_t positiveRemainder(int16_t x, uint16_t y)
152 { int16_t xMody = x % y;
153  if(xMody < 0) return uint16_t(y + xMody);
154  else return xMody;
155 }
156 
158 inline bool fftSuitable(int N)
159 { static std::array<int,4> primes = {{2,3,5,7}};
160  int tmpN = N;
161  for(int p: primes) while(tmpN % p == 0) tmpN /= p;
162  //All suitable prime factors taken out, we should be left with 1 for a suitable N:
163  return (tmpN==1);
164 }
165 
167 template<typename Enum>
169 {
170  std::map<string,Enum> stringToEnum;
171  std::map<Enum,string> enumToString;
172  void addEntry() {}
173  template<typename...Args> void addEntry(Enum e, const string& s, Args...args)
174  { stringToEnum[s]=e; enumToString[e]=s;
175  addEntry(args...);
176  }
177 public:
178  //Initialize using the convenient syntax:
179  // EnumStringMap mapname(enum1, string1, enum2, string2, ... as many as needed!)
180  template<typename...Args> EnumStringMap(Args...args) { addEntry(args...); }
181 
182  //Match a key string to an enum, return false if not found
183  bool getEnum(const char* key, Enum& e) const
184  { typename std::map<string,Enum>::const_iterator i = stringToEnum.find(key);
185  if(i==stringToEnum.end()) return false;
186  else
187  { e = i->second;
188  return true;
189  }
190  }
191 
192  //Return the string representation of the enum:
193  const char* getString(Enum e) const
194  { typename std::map<Enum,string>::const_iterator i = enumToString.find(e);
195  return i->second.c_str();
196  }
197 
198  string optionList() const
199  { typename std::map<string,Enum>::const_iterator i=stringToEnum.begin();
200  string ret = i->first; i++;
201  for(; i!=stringToEnum.end(); i++) ret += ("|"+i->first);
202  return ret;
203  }
204 };
205 
206 #endif //JDFTX_CORE_UTIL_H
Definition: Util.h:133
A template to ease option parsing (maps enums <–> strings)
Definition: Util.h:168
Definition: Util.h:84
void initSystemCmdline(int argc, char **argv, const char *description, string &inputFilename, bool &dryRun, bool &printDefaults)
initSystem along with commandline options
void printVersionBanner()
Print package name, version, revision etc. to log.
bool mpiDebugLog
If true, all processes output to seperate debug log files, otherwise only head process outputs (set b...
off_t fileSize(const char *filename)
Get the size of a file.
int assertStackTraceExit(const char *expr, const char *function, const char *file, long line)
void finalizeSystem(bool successful=true)
Clean-up corresponding to initSystem(), final messages (depending on successful) and clean-up MPI...
double clock_sec()
Elapsed time in microseconds (from start of program)
void logResume()
re-enable logging after a logSuspend() call
bool killFlag
Flag set by signal handlers - all compute loops should quit cleanly when this is set.
void printStack(bool detailedStackScript=false)
Print a minimal stack trace and optionally write a script that, when run, will print a more detailed ...
MPI wrapper class.
Definition: MPIUtil.h:33
FILE * nullLog
pointer to /dev/null
bool fftSuitable(int N)
Check if an integer is suitable for Fast Fourier Transforms (small prime factors only) ...
Definition: Util.h:158
uint16_t positiveRemainder(int16_t x, uint16_t y)
For any x and y>0, compute z = x % y such that 0 <= z < y.
Definition: Util.h:151
void stackTraceExit(int code)
Exit on error with stack trace.
void initSystem(int argc, char **argv)
Init MPI (if not already done), print banner, set up threads (play nice with job schedulers), GPU and signal handlers.
void logSuspend()
temporarily disable all log output (until logResume())