Block-Structured AMR Software Framework
AMReX_Utility.H
Go to the documentation of this file.
1 #ifndef BL_UTILITY_H
2 #define BL_UTILITY_H
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_BLassert.H>
6 #include <AMReX_REAL.H>
7 #include <AMReX_INT.H>
8 #include <AMReX_Array.H>
9 #include <AMReX_Vector.H>
10 #include <AMReX_Box.H>
11 #include <AMReX_BoxArray.H>
12 #include <AMReX_Demangle.H>
15 #include <AMReX_Random.H>
16 #include <AMReX_GpuQualifiers.H>
17 #include <AMReX_FileSystem.H>
18 #include <AMReX_String.H>
19 
20 #include <cfloat>
21 #include <chrono>
22 #include <climits>
23 #include <cstdlib>
24 #include <iostream>
25 #include <limits>
26 #include <map>
27 #include <sstream>
28 #include <string>
29 #include <typeinfo>
30 #include <type_traits>
31 
32 namespace amrex
33 {
39  bool is_integer (const char* str);
40 
42  template <typename T> bool is_it (std::string const& s, T& v);
43 
45  const std::vector<std::string>& Tokenize (const std::string& instr,
46  const std::string& separators);
47 
72  bool UtilCreateDirectory (const std::string& path,
73  mode_t mode,
74  bool verbose = false);
76  void CreateDirectoryFailed (const std::string& dir);
78  void FileOpenFailed (const std::string& file);
85  bool FileExists(const std::string &filename);
87  std::string UniqueString();
89  void UtilCreateCleanDirectory (const std::string &path,
90  bool callbarrier = true);
91 
93 
97  void UtilCreateDirectoryDestructive(const std::string &path,
98  bool callbarrier = true);
99 
101  void UtilRenameDirectoryToOld (const std::string &path,
102  bool callbarrier = true);
108  void OutOfMemory ();
126  double InvNormDist (double p);
149  double InvNormDistBest (double p);
150 
151  /* \brief cumulative refinement ratio between levels */
152  int CRRBetweenLevels(int fromlevel, int tolevel,
153  const Vector<int> &refratios);
154 
155  class expect;
156  std::istream& operator>>(std::istream&, const expect& exp);
157 
158  class expect
159  {
160  friend std::istream& operator>>(std::istream&, const expect& exp);
161  public:
162  explicit expect (std::string str_);
163  explicit expect (const char* istr_);
164  explicit expect (char c);
165  [[nodiscard]] const std::string& the_string( ) const;
166  private:
167  std::string istr;
168  };
169 
171  {
172  public:
173  StreamRetry(std::ostream &os, std::string suffix, int maxtries);
174  StreamRetry(std::string filename, bool abortonretryfailure, int maxtries);
175  bool TryOutput();
176  bool TryFileOutput();
177  static int NStreamErrors() { return nStreamErrors; }
178  static void ClearStreamErrors() { nStreamErrors = 0; }
179 
180  private:
182  bool abortOnRetryFailure = true;
183  std::string fileName;
184  std::ostream *sros;
185  std::ostream::pos_type spos;
186  std::string suffix;
187 
188  static int nStreamErrors;
189  };
190 
193  void SyncStrings(const Vector<std::string> &localStrings,
194  Vector<std::string> &syncedStrings, bool &alreadySynced);
195 
196  //
197  // Memory Usage Counting
198  //
199  // For gcc, there are extra 32 bytes for each map node.
200  // For others, this number may be different.
201  static const Long gcc_map_node_extra_bytes = 32L;
202  template <typename T> Long bytesOf (const std::vector<T>& v);
203  template <typename Key, typename T, class Compare> Long bytesOf (const std::map<Key,T,Compare>& m);
204 
205  void BroadcastBool(bool &bBool, int myLocalId, int rootId, const MPI_Comm &localComm);
206 
207  void BroadcastString(std::string &bStr, int myLocalId, int rootId, const MPI_Comm &localComm);
208  void BroadcastStringArray(Vector<std::string> &bSA, int myLocalId, int rootId, const MPI_Comm &localComm);
209 
210  template<class T> void BroadcastArray(Vector<T> &aT, int myLocalId, int rootId, const MPI_Comm &localComm);
211 
212  void Sleep (double sleepsec); // Sleep for sleepsec seconds
213 
214 
215  using MaxResSteadyClock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
216  std::chrono::high_resolution_clock,
217  std::chrono::steady_clock>;
218  double second () noexcept;
219 
220  template<typename T> void hash_combine (uint64_t & seed, const T & val) noexcept;
221  template<typename T> uint64_t hash_vector (const Vector<T> & vec, uint64_t seed = 0xDEADBEEFDEADBEEF) noexcept;
222 
223 }
224 
225 template <typename T>
226 bool amrex::is_it (std::string const& s, T& v)
227 {
228  std::istringstream ss(s);
229  if (ss >> v) {
230  std::string left;
231  std::getline(ss, left);
232  return left.empty();
233  } else {
234  return false;
235  }
236 }
237 
238 template<class T> void amrex::BroadcastArray(Vector<T> &aT, int myLocalId, int rootId, const MPI_Comm &localComm)
239 {
240  int aT_Size(-2);
241  if(myLocalId == rootId) {
242  aT_Size = aT.size();
243  }
244  ParallelDescriptor::Bcast(&aT_Size, 1, rootId, localComm);
245  BL_ASSERT(aT_Size >= 0);
246  if(myLocalId != rootId) {
247  aT.resize(aT_Size);
248  }
249  if(aT_Size > 0) {
250  ParallelDescriptor::Bcast(aT.dataPtr(), aT.size(), rootId, localComm);
251  }
252 }
253 
254 
255 //
256 // I'm going to document right here all the BL macros that aren't documented
257 // anywhere else. Note that all these #ifdef ... #endif blocks are necessary
258 // to get doc++ to properly document the macros.
259 //
260 
261 #ifdef BL_LANG_FORT
262 #undef BL_LANG_FORT
263 /*
264  The macro BL_LANG_FORT indicates that Fortran code is being compiled.
265 */
266 #define BL_LANG_FORT 1
267 #endif /*BL_LANG_FORT*/
268 
269 #ifdef BL_FORT_USE_UNDERSCORE
270 #undef BL_FORT_USE_UNDERSCORE
271 /*
272  The macro BL_FORT_USE_UNDERSCORE indicates that C++ code should call
273  Fortran routines by appending an underscore to the name of the Fortran
274  routine. This is set automatically by the make subsystem.
275 
276  For example, if the Fortran routine is named abcxyx, then it will
277  be called in C++ code as abcxyz_.
278 */
279 #define BL_FORT_USE_UNDERSCORE 1
280 #endif /*BL_FORT_USE_UNDERSCORE*/
281 
282 #ifdef BL_FORT_USE_UPPERCASE
283 #undef BL_FORT_USE_UPPERCASE
284 /*
285  The macro BL_FORT_USE_UPPERCASE indicates that C++ code should call
286  Fortran routines using uppercase letters for all the letters in the
287  routine. This is set automatically by the make subsystem.
288 
289  For example, if the Fortran routine is named abcxyx, then it will
290  be called in C++ code as ABCXYZ.
291 */
292 #define BL_FORT_USE_UPPERCASE 1
293 #endif /*BL_FORT_USE_UPPERCASE*/
294 
295 #ifdef BL_FORT_USE_LOWERCASE
296 #undef BL_FORT_USE_LOWERCASE
297 /*
298  The macro BL_FORT_USE_LOWERCASE indicates that C++ code should call
299  Fortran routines using lowercase letters for all the letters in the
300  routine. This is set automatically by the make subsystem.
301 
302  For example, if the Fortran routine is named abcxyx, then it will
303  be called in C++ code as abcxyx.
304 */
305 #define BL_FORT_USE_LOWERCASE 1
306 #endif /*BL_FORT_USE_LOWERCASE*/
307 
308 /*
309  BL_IGNORE_MAX is a macro that expands to the literal value 100000. It is
310  defined when compiling either Fortran or C++ code; i.e. when either
311  BL_LANG_CC or BL_LANG_FORT is defined. It is used in calls to
312  istream::ignore() in the AMReX code when reading in characters from an
313  istream. We use this macro instead of the more proper INT_MAX from
314  <limits> since at least one compiler didn't work properly when
315  istream::ignore() was passed INT_MAX.
316 */
317 #define BL_IGNORE_MAX 100000
318 
319 // \cond CODEGEN
320 template <typename T>
321 amrex::Long
322 amrex::bytesOf (const std::vector<T>& v)
323 {
324  return sizeof(v) + v.capacity()*sizeof(T);
325 }
326 
327 template <typename Key, typename T, class Compare>
328 amrex::Long
329 amrex::bytesOf (const std::map<Key,T,Compare>& m)
330 {
331  return sizeof(m) + m.size()*(sizeof(Key)+sizeof(T)+gcc_map_node_extra_bytes);
332 }
333 // \endcond
334 
335 extern "C" {
336  void* amrex_malloc (std::size_t size);
337  void amrex_free (void* p);
338 }
339 
340 // hash combiner borrowed from Boost
341 /*
342 Boost Software License - Version 1.0 - August 17th, 2003
343 
344 Permission is hereby granted, free of charge, to any person or organization
345 obtaining a copy of the software and accompanying documentation covered by
346 this license (the "Software") to use, reproduce, display, distribute,
347 execute, and transmit the Software, and to prepare derivative works of the
348 Software, and to permit third-parties to whom the Software is furnished to
349 do so, all subject to the following:
350 
351 The copyright notices in the Software and this entire statement, including
352 the above license grant, this restriction and the following disclaimer,
353 must be included in all copies of the Software, in whole or in part, and
354 all derivative works of the Software, unless such copies or derivative
355 works are solely in the form of machine-executable object code generated by
356 a source language processor.
357 
358 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
359 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
360 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
361 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
362 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
363 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
364 DEALINGS IN THE SOFTWARE.
365 */
366 template<typename T>
367 void
368 amrex::hash_combine (uint64_t & seed, const T & val) noexcept
369 {
370  seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed<<6) + (seed>>2);
371 }
372 
373 template<typename T>
374 uint64_t
375 amrex::hash_vector (const Vector<T> & vec, uint64_t seed) noexcept
376 {
377  for (const auto & x: vec) {
378  hash_combine(seed, x);
379  }
380  return seed;
381 }
382 
383 #endif /*BL_UTILITY_H*/
#define BL_ASSERT(EX)
Definition: AMReX_BLassert.H:39
void amrex_free(void *p)
Definition: AMReX_Utility.cpp:936
void * amrex_malloc(std::size_t size)
Definition: AMReX_Utility.cpp:930
int MPI_Comm
Definition: AMReX_ccse-mpi.H:47
Definition: AMReX_Utility.H:171
std::ostream::pos_type spos
Definition: AMReX_Utility.H:185
bool TryFileOutput()
Definition: AMReX_Utility.cpp:632
int maxTries
Definition: AMReX_Utility.H:181
static void ClearStreamErrors()
Definition: AMReX_Utility.H:178
std::string fileName
Definition: AMReX_Utility.H:183
static int nStreamErrors
Definition: AMReX_Utility.H:188
StreamRetry(std::ostream &os, std::string suffix, int maxtries)
Definition: AMReX_Utility.cpp:565
std::string suffix
Definition: AMReX_Utility.H:186
bool abortOnRetryFailure
Definition: AMReX_Utility.H:182
int tries
Definition: AMReX_Utility.H:181
bool TryOutput()
Definition: AMReX_Utility.cpp:581
static int NStreamErrors()
Definition: AMReX_Utility.H:177
std::ostream * sros
Definition: AMReX_Utility.H:184
Long size() const noexcept
Definition: AMReX_Vector.H:50
T * dataPtr() noexcept
get access to the underlying data pointer
Definition: AMReX_Vector.H:46
Definition: AMReX_Utility.H:159
friend std::istream & operator>>(std::istream &, const expect &exp)
std::string istr
Definition: AMReX_Utility.H:167
expect(std::string str_)
Definition: AMReX_Utility.cpp:542
const std::string & the_string() const
Definition: AMReX_Utility.cpp:553
std::tuple< IntVectND< 3 >, Direction, Kind > Key
Definition: AMReX_FFT_Helper.H:1134
AMREX_GPU_HOST_DEVICE Long size(T const &b) noexcept
integer version
Definition: AMReX_GpuRange.H:26
void Bcast(void *, int, MPI_Datatype, int, MPI_Comm)
Definition: AMReX_ParallelDescriptor.cpp:1282
Definition: AMReX_Amr.cpp:49
void SyncStrings(const Vector< std::string > &localStrings, Vector< std::string > &syncedStrings, bool &alreadySynced)
Definition: AMReX_Utility.cpp:677
double InvNormDistBest(double p)
This function returns an approximation of the inverse cumulative standard normal distribution functio...
Definition: AMReX_Utility.cpp:393
void FileOpenFailed(const std::string &file)
Output a message and abort when couldn't open the file.
Definition: AMReX_Utility.cpp:131
bool is_integer(const char *str)
Useful C++ Utility Functions.
Definition: AMReX_Utility.cpp:35
int CRRBetweenLevels(int fromlevel, int tolevel, const Vector< int > &refratios)
Definition: AMReX_Utility.cpp:238
void BroadcastStringArray(Vector< std::string > &bSA, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition: AMReX_Utility.cpp:899
Vector< std::string > UnSerializeStringArray(const Vector< char > &charArray)
Definition: AMReX_Utility.cpp:853
std::conditional_t< std::chrono::high_resolution_clock::is_steady, std::chrono::high_resolution_clock, std::chrono::steady_clock > MaxResSteadyClock
Definition: AMReX_Utility.H:217
bool FileExists(const std::string &filename)
Check if a file already exists. Return true if the filename is an existing file, directory,...
Definition: AMReX_Utility.cpp:139
bool is_it(std::string const &s, T &v)
Return true and store value in v if string s is type T.
Definition: AMReX_Utility.H:226
const std::vector< std::string > & Tokenize(const std::string &instr, const std::string &separators)
Splits "instr" into separate pieces based on "separators".
Definition: AMReX_Utility.cpp:61
double second() noexcept
Definition: AMReX_Utility.cpp:922
uint64_t hash_vector(const Vector< T > &vec, uint64_t seed=0xDEADBEEFDEADBEEF) noexcept
Definition: AMReX_Utility.H:375
Long bytesOf(const std::vector< T > &v)
void UtilCreateCleanDirectory(const std::string &path, bool callbarrier=true)
Create a new directory, renaming the old one if it exists.
Definition: AMReX_Utility.cpp:161
void CreateDirectoryFailed(const std::string &dir)
Output a message and abort when couldn't create the directory.
Definition: AMReX_Utility.cpp:123
void BroadcastArray(Vector< T > &aT, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition: AMReX_Utility.H:238
bool UtilCreateDirectory(const std::string &path, mode_t mode, bool verbose=false)
Creates the specified directories. path may be either a full pathname or a relative pathname....
Definition: AMReX_Utility.cpp:116
void BroadcastString(std::string &bStr, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition: AMReX_Utility.cpp:883
Vector< char > SerializeStringArray(const Vector< std::string > &stringArray)
Definition: AMReX_Utility.cpp:839
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > exp(const GpuComplex< T > &a_z) noexcept
Complex expotential function.
Definition: AMReX_GpuComplex.H:334
void hash_combine(uint64_t &seed, const T &val) noexcept
Definition: AMReX_Utility.H:368
int verbose
Definition: AMReX_DistributionMapping.cpp:36
void Sleep(double sleepsec)
Definition: AMReX_Utility.cpp:913
void UtilRenameDirectoryToOld(const std::string &path, bool callbarrier=true)
Rename a current directory if it exists.
Definition: AMReX_Utility.cpp:211
static const Long gcc_map_node_extra_bytes
Definition: AMReX_Utility.H:201
double InvNormDist(double p)
This function returns an approximation of the inverse cumulative standard normal distribution functio...
Definition: AMReX_Utility.cpp:272
void UtilCreateDirectoryDestructive(const std::string &path, bool callbarrier=true)
Definition: AMReX_Utility.cpp:186
std::string UniqueString()
Create a (probably) unique string.
Definition: AMReX_Utility.cpp:145
std::istream & operator>>(std::istream &is, BoxND< dim > &bx)
Read from istream.
Definition: AMReX_Box.H:1700
void BroadcastBool(bool &bBool, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition: AMReX_Utility.cpp:868
void OutOfMemory()
Aborts after printing message indicating out-of-memory; i.e. operator new has failed....
Definition: AMReX_Utility.cpp:232