JDFTx  1.0.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 
51 inline double clock_us()
52 { timeval tv;
53  gettimeofday(&tv,NULL);
54  return ((tv.tv_sec & 0x1fffff) * 1e6) + tv.tv_usec;
55 }
56 
63 #define TIME(title,fp,code) \
64 { double runTime = clock_us(); \
65  { code } \
66  runTime = clock_us() - runTime; \
67  fprintf(fp, "%s took %.2le s.\n", title, runTime*1e-6); \
68 }
69 
74 #ifdef ENABLE_PROFILING
75 class StopWatch
76 {
77 public:
78  StopWatch(string name);
79  void start();
80  void stop();
81  void print() const;
82 private:
83  double tPrev, Ttot, TsqTot; int nT;
84  string name;
85 };
86 #else //ENABLE_PROFILING
87 //Version which does no profiling for release versions
88 class StopWatch
89 {
90 public:
91  StopWatch(string name) {}
92  void start() {}
93  void stop() {}
94 };
95 #endif //ENABLE_PROFILING
96 
97 
98 
99 // ----------- Debugging ---------------
100 void printStack(bool detailedStackScript=false);
101 void stackTraceExit(int code);
102 int assertStackTraceExit(const char* expr, const char* function, const char* file, long line);
103 #define assert(expr) \
105  (void)((expr) ? 0 : assertStackTraceExit(#expr, __func__, __FILE__, __LINE__))
106 
107 
108 // ----------- Logging ---------------
109 extern FILE* globalLog;
110 extern FILE* nullLog;
111 void logSuspend();
112 void logResume();
113 
114 #define logPrintf(...) fprintf(globalLog, __VA_ARGS__)
115 #define logFlush() fflush(globalLog)
116 
117 #define die(...) \
119  { fprintf(globalLog, __VA_ARGS__); \
120  if(mpiUtil->isHead() && globalLog != stdout) \
121  fprintf(stderr, __VA_ARGS__); \
122  finalizeSystem(false); \
123  exit(1); \
124  }
125 
127 #define die_alone(...) \
128  { fprintf(globalLog, __VA_ARGS__); \
129  fflush(globalLog); \
130  if(mpiUtil->isHead() && globalLog != stdout) \
131  fprintf(stderr, __VA_ARGS__); \
132  if(mpiUtil->nProcesses() == 1) finalizeSystem(false); /* Safe to call only if no other process */ \
133  mpiUtil->exit(1); \
134  }
135 
136 //--------------- Citations --------------------
137 namespace Citations
138 {
139  void add(string reason, string paper);
141 
143  void print(FILE* fp=globalLog);
144 }
145 
146 
147 //--------------- Miscellaneous ------------------
148 
149 
150 #include <sys/stat.h>
152 off_t fileSize(const char *filename);
153 
155 inline uint16_t positiveRemainder(int16_t x, uint16_t y)
156 { int16_t xMody = x % y;
157  if(xMody < 0) return uint16_t(y + xMody);
158  else return xMody;
159 }
160 
162 inline bool fftSuitable(int N)
163 { static std::array<int,4> primes = {{2,3,5,7}};
164  int tmpN = N;
165  for(int p: primes) while(tmpN % p == 0) tmpN /= p;
166  //All suitable prime factors taken out, we should be left with 1 for a suitable N:
167  return (tmpN==1);
168 }
169 
171 template<typename Enum>
173 {
174  std::map<string,Enum> stringToEnum;
175  std::map<Enum,string> enumToString;
176  void addEntry() {}
177  template<typename...Args> void addEntry(Enum e, const string& s, Args...args)
178  { stringToEnum[s]=e; enumToString[e]=s;
179  addEntry(args...);
180  }
181 public:
182  //Initialize using the convenient syntax:
183  // EnumStringMap mapname(enum1, string1, enum2, string2, ... as many as needed!)
184  template<typename...Args> EnumStringMap(Args...args) { addEntry(args...); }
185 
186  //Match a key string to an enum, return false if not found
187  bool getEnum(const char* key, Enum& e) const
188  { typename std::map<string,Enum>::const_iterator i = stringToEnum.find(key);
189  if(i==stringToEnum.end()) return false;
190  else
191  { e = i->second;
192  return true;
193  }
194  }
195 
196  //Return the string representation of the enum:
197  const char* getString(Enum e) const
198  { typename std::map<Enum,string>::const_iterator i = enumToString.find(e);
199  return i->second.c_str();
200  }
201 
202  string optionList() const
203  { typename std::map<string,Enum>::const_iterator i=stringToEnum.begin();
204  string ret = i->first; i++;
205  for(; i!=stringToEnum.end(); i++) ret += ("|"+i->first);
206  return ret;
207  }
208 };
209 
210 #endif //JDFTX_CORE_UTIL_H
Definition: Util.h:137
A template to ease option parsing (maps enums <–> strings)
Definition: Util.h:172
Definition: Util.h:88
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...
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:162
double clock_us()
Time of day in microseconds.
Definition: Util.h:51
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:155
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())