JDFTx  1.1.2
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 
150 //Endianness utilities (all binary I/O is from little-endian files regardless of operating endianness):
151 void convertToLE(void* ptr, size_t size, size_t nmemb);
152 void convertFromLE(void* ptr, size_t size, size_t nmemb);
153 size_t freadLE(void *ptr, size_t size, size_t nmemb, FILE* fp);
154 size_t fwriteLE(const void *ptr, size_t size, size_t nmemb, FILE *fp);
155 
157 inline uint16_t positiveRemainder(int16_t x, uint16_t y)
158 { int16_t xMody = x % y;
159  if(xMody < 0) return uint16_t(y + xMody);
160  else return xMody;
161 }
162 
164 inline bool fftSuitable(int N)
165 { static std::array<int,4> primes = {{2,3,5,7}};
166  int tmpN = N;
167  for(int p: primes) while(tmpN % p == 0) tmpN /= p;
168  //All suitable prime factors taken out, we should be left with 1 for a suitable N:
169  return (tmpN==1);
170 }
171 
173 template<typename Enum>
175 {
176  std::map<string,Enum> stringToEnum;
177  std::map<Enum,string> enumToString;
178  void addEntry() {}
179  template<typename...Args> void addEntry(Enum e, const string& s, Args...args)
180  { stringToEnum[s]=e; enumToString[e]=s;
181  addEntry(args...);
182  }
183 public:
184  //Initialize using the convenient syntax:
185  // EnumStringMap mapname(enum1, string1, enum2, string2, ... as many as needed!)
186  template<typename...Args> EnumStringMap(Args...args) { addEntry(args...); }
187 
188  //Match a key string to an enum, return false if not found
189  bool getEnum(const char* key, Enum& e) const
190  { typename std::map<string,Enum>::const_iterator i = stringToEnum.find(key);
191  if(i==stringToEnum.end()) return false;
192  else
193  { e = i->second;
194  return true;
195  }
196  }
197 
198  //Return the string representation of the enum:
199  const char* getString(Enum e) const
200  { typename std::map<Enum,string>::const_iterator i = enumToString.find(e);
201  return i->second.c_str();
202  }
203 
204  string optionList() const
205  { typename std::map<string,Enum>::const_iterator i=stringToEnum.begin();
206  string ret = i->first; i++;
207  for(; i!=stringToEnum.end(); i++) ret += ("|"+i->first);
208  return ret;
209  }
210 };
211 
212 #endif //JDFTX_CORE_UTIL_H
Definition: Util.h:133
A template to ease option parsing (maps enums <–> strings)
Definition: Util.h:174
Definition: Util.h:84
void convertFromLE(void *ptr, size_t size, size_t nmemb)
Convert data from little-endian to operating endianness.
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.
size_t freadLE(void *ptr, size_t size, size_t nmemb, FILE *fp)
Read from a little-endian binary file, regardless of operating endianness.
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.
size_t fwriteLE(const void *ptr, size_t size, size_t nmemb, FILE *fp)
Write to a little-endian binary file, regardless of operating endianness.
void convertToLE(void *ptr, size_t size, size_t nmemb)
Convert data from operating endianness to little-endian.
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:164
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:157
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())