Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
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#include <AMReX_TypeTraits.H>
20
21#include <cfloat>
22#include <chrono>
23#include <climits>
24#include <cstdlib>
25#include <iostream>
26#include <limits>
27#include <map>
28#include <ostream>
29#include <sstream>
30#include <string>
31#include <string_view>
32#include <tuple>
33#include <typeinfo>
34#include <type_traits>
35#include <utility>
36
37namespace amrex
38{
44 bool is_integer (const char* str);
45
47 template <typename T> bool is_it (std::string const& s, T& v);
48
50 const std::vector<std::string>& Tokenize (const std::string& instr,
51 const std::string& separators);
52
77 bool UtilCreateDirectory (const std::string& path,
78 mode_t mode,
79 bool verbose = false);
81 void CreateDirectoryFailed (const std::string& dir);
83 void FileOpenFailed (const std::string& file);
90 bool FileExists(const std::string &filename);
92 std::string UniqueString();
94 void UtilCreateCleanDirectory (const std::string &path,
95 bool callbarrier = true);
96
98 void UtilCreateDirectoryDestructive(const std::string &path,
99 bool callbarrier = true);
100
102 void UtilRenameDirectoryToOld (const std::string &path,
103 bool callbarrier = true);
109 void OutOfMemory ();
127 double InvNormDist (double p);
150 double InvNormDistBest (double p);
151
152 /* \brief cumulative refinement ratio between levels */
153 int CRRBetweenLevels(int fromlevel, int tolevel,
154 const Vector<int> &refratios);
155
156 class expect;
157 std::istream& operator>>(std::istream&, const expect& exp);
158
159 class expect
160 {
161 friend std::istream& operator>>(std::istream&, const expect& exp);
162 public:
163 explicit expect (std::string str_);
164 explicit expect (const char* istr_);
165 explicit expect (char c);
166 [[nodiscard]] const std::string& the_string( ) const;
167 private:
168 std::string istr;
169 };
170
172 {
173 public:
174 StreamRetry(std::ostream &os, std::string suffix, int maxtries);
175 StreamRetry(std::string filename, bool abortonretryfailure, int maxtries);
176 bool TryOutput();
177 bool TryFileOutput();
178 static int NStreamErrors() { return nStreamErrors; }
179 static void ClearStreamErrors() { nStreamErrors = 0; }
180
181 private:
184 std::string fileName;
185 std::ostream *sros;
186 std::ostream::pos_type spos;
187 std::string suffix;
188
189 static int nStreamErrors;
190 };
191
194 void SyncStrings(const Vector<std::string> &localStrings,
195 Vector<std::string> &syncedStrings, bool &alreadySynced);
196
197 //
198 // Memory Usage Counting
199 //
200 // For gcc, there are extra 32 bytes for each map node.
201 // For others, this number may be different.
202 static const Long gcc_map_node_extra_bytes = 32L;
203 template <typename T> Long bytesOf (const std::vector<T>& v);
204 template <typename Key, typename T, class Compare> Long bytesOf (const std::map<Key,T,Compare>& m);
205
206 void BroadcastBool(bool &bBool, int myLocalId, int rootId, const MPI_Comm &localComm);
207
208 void BroadcastString(std::string &bStr, int myLocalId, int rootId, const MPI_Comm &localComm);
209 void BroadcastStringArray(Vector<std::string> &bSA, int myLocalId, int rootId, const MPI_Comm &localComm);
210
211 template<class T> void BroadcastArray(Vector<T> &aT, int myLocalId, int rootId, const MPI_Comm &localComm);
212
213 void Sleep (double sleepsec); // Sleep for sleepsec seconds
214
215
216 using MaxResSteadyClock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
217 std::chrono::high_resolution_clock,
218 std::chrono::steady_clock>;
219 double second () noexcept;
220
221 template<typename T> void hash_combine (uint64_t & seed, const T & val) noexcept;
222 template<typename T> uint64_t hash_vector (const Vector<T> & vec, uint64_t seed = 0xDEADBEEFDEADBEEF) noexcept;
223
224 template <class T>
225 std::ostream& ToString(std::ostream& os,
226 const T& t,
227 const char* symbol_begin = "[",
228 const char* symbol_delim = ", ",
229 const char* symbol_end = "]",
230 const char* symbol_str = "\"",
231 int limit = 100);
232
233 template <class T>
234 std::string ToString(const T& t,
235 const char* symbol_begin = "[",
236 const char* symbol_delim = ", ",
237 const char* symbol_end = "]",
238 const char* symbol_str = "\"",
239 int limit = 100,
240 std::ostringstream ss = std::ostringstream{});
241
251 template <typename F, typename... T>
253 auto callNoinline (F const& f, T&&... arg)
254 -> decltype(std::declval<F>()(std::declval<T>()...)); // needed for nvcc
255}
256
257template <typename T>
258bool amrex::is_it (std::string const& s, T& v)
259{
260 std::istringstream ss(s);
261 if (ss >> v) {
262 std::string left;
263 std::getline(ss, left);
264 return left.empty();
265 } else {
266 return false;
267 }
268}
269
270template<class T> void amrex::BroadcastArray(Vector<T> &aT, int myLocalId, int rootId, const MPI_Comm &localComm)
271{
272 int aT_Size(-2);
273 if(myLocalId == rootId) {
274 aT_Size = aT.size();
275 }
276 ParallelDescriptor::Bcast(&aT_Size, 1, rootId, localComm);
277 BL_ASSERT(aT_Size >= 0);
278 if(myLocalId != rootId) {
279 aT.resize(aT_Size);
280 }
281 if(aT_Size > 0) {
282 ParallelDescriptor::Bcast(aT.dataPtr(), aT.size(), rootId, localComm);
283 }
284}
285
286
287//
288// I'm going to document right here all the BL macros that aren't documented
289// anywhere else. Note that all these #ifdef ... #endif blocks are necessary
290// to get doc++ to properly document the macros.
291//
292
293#ifdef BL_LANG_FORT
294#undef BL_LANG_FORT
295/*
296 The macro BL_LANG_FORT indicates that Fortran code is being compiled.
297*/
298#define BL_LANG_FORT 1
299#endif /*BL_LANG_FORT*/
300
301#ifdef BL_FORT_USE_UNDERSCORE
302#undef BL_FORT_USE_UNDERSCORE
303/*
304 The macro BL_FORT_USE_UNDERSCORE indicates that C++ code should call
305 Fortran routines by appending an underscore to the name of the Fortran
306 routine. This is set automatically by the make subsystem.
307
308 For example, if the Fortran routine is named abcxyx, then it will
309 be called in C++ code as abcxyz_.
310*/
311#define BL_FORT_USE_UNDERSCORE 1
312#endif /*BL_FORT_USE_UNDERSCORE*/
313
314#ifdef BL_FORT_USE_UPPERCASE
315#undef BL_FORT_USE_UPPERCASE
316/*
317 The macro BL_FORT_USE_UPPERCASE indicates that C++ code should call
318 Fortran routines using uppercase letters for all the letters in the
319 routine. This is set automatically by the make subsystem.
320
321 For example, if the Fortran routine is named abcxyx, then it will
322 be called in C++ code as ABCXYZ.
323*/
324#define BL_FORT_USE_UPPERCASE 1
325#endif /*BL_FORT_USE_UPPERCASE*/
326
327#ifdef BL_FORT_USE_LOWERCASE
328#undef BL_FORT_USE_LOWERCASE
329/*
330 The macro BL_FORT_USE_LOWERCASE indicates that C++ code should call
331 Fortran routines using lowercase letters for all the letters in the
332 routine. This is set automatically by the make subsystem.
333
334 For example, if the Fortran routine is named abcxyx, then it will
335 be called in C++ code as abcxyx.
336*/
337#define BL_FORT_USE_LOWERCASE 1
338#endif /*BL_FORT_USE_LOWERCASE*/
339
340/*
341 BL_IGNORE_MAX is a macro that expands to the literal value 100000. It is
342 defined when compiling either Fortran or C++ code; i.e. when either
343 BL_LANG_CC or BL_LANG_FORT is defined. It is used in calls to
344 istream::ignore() in the AMReX code when reading in characters from an
345 istream. We use this macro instead of the more proper INT_MAX from
346 <limits> since at least one compiler didn't work properly when
347 istream::ignore() was passed INT_MAX.
348*/
349#define BL_IGNORE_MAX 100000
350
351// \cond CODEGEN
352template <typename T>
353amrex::Long
354amrex::bytesOf (const std::vector<T>& v)
355{
356 return sizeof(v) + v.capacity()*sizeof(T);
357}
358
359template <typename Key, typename T, class Compare>
360amrex::Long
361amrex::bytesOf (const std::map<Key,T,Compare>& m)
362{
363 return sizeof(m) + m.size()*(sizeof(Key)+sizeof(T)+gcc_map_node_extra_bytes);
364}
365// \endcond
366
367extern "C" {
368 void* amrex_malloc (std::size_t size);
369 void amrex_free (void* p);
370}
371
372// hash combiner borrowed from Boost
373/*
374Boost Software License - Version 1.0 - August 17th, 2003
375
376Permission is hereby granted, free of charge, to any person or organization
377obtaining a copy of the software and accompanying documentation covered by
378this license (the "Software") to use, reproduce, display, distribute,
379execute, and transmit the Software, and to prepare derivative works of the
380Software, and to permit third-parties to whom the Software is furnished to
381do so, all subject to the following:
382
383The copyright notices in the Software and this entire statement, including
384the above license grant, this restriction and the following disclaimer,
385must be included in all copies of the Software, in whole or in part, and
386all derivative works of the Software, unless such copies or derivative
387works are solely in the form of machine-executable object code generated by
388a source language processor.
389
390THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
391IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
392FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
393SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
394FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
395ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
396DEALINGS IN THE SOFTWARE.
397*/
398template<typename T>
399void
400amrex::hash_combine (uint64_t & seed, const T & val) noexcept
401{
402 seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed<<6) + (seed>>2);
403}
404
405template<typename T>
406uint64_t
407amrex::hash_vector (const Vector<T> & vec, uint64_t seed) noexcept
408{
409 for (const auto & x: vec) {
410 hash_combine(seed, x);
411 }
412 return seed;
413}
414
415
416namespace amrex::detail {
417
418 // Determine if type has .begin() and .end() member functions
419 template <class T>
420 constexpr decltype((std::declval<T>().begin(), std::declval<T>().end(), true)) HasBeginEnd() {
421 return true;
422 }
423 template <class T, class... Args>
424 constexpr bool HasBeginEnd(Args...) {
425 return false;
426 }
427
428 // Determine if type has a specialization for std::tuple_size
429 template <class T>
430 constexpr decltype((std::tuple_size<T>::value, true)) HasTupleSize() {
431 return true;
432 }
433 template <class T, class... Args>
434 constexpr bool HasTupleSize(Args...) {
435 return false;
436 }
437
438 // Helper for tuple unpacking
439 template <class T, std::size_t... idx>
440 void ToStringTupleImp(std::index_sequence<idx...>, std::ostream& os, const T& t,
441 const char* symbol_begin, const char* symbol_delim,
442 const char* symbol_end, const char* symbol_str, int limit) {
443 os << symbol_begin;
444 Long count = 0;
445 auto op = [&](auto& value) {
446 if (count > 0 && (count <= limit || limit < 0)) {
447 os << symbol_delim;
448 }
449 if (count < limit || limit < 0) {
450 ToString(os, value, symbol_begin, symbol_delim, symbol_end,
451 symbol_str, limit);
452 } else if (count == limit) {
453 os << "...";
454 }
455 ++count;
456 };
457 (op(std::get<idx>(t)), ...);
458 os << symbol_end;
459 }
460}
461
462template <class T>
463std::ostream& amrex::ToString(std::ostream& os, const T& t, const char* symbol_begin,
464 const char* symbol_delim, const char* symbol_end,
465 const char* symbol_str, int limit)
466{
467 if constexpr (std::is_same_v<std::string, T> ||
468 std::is_same_v<std::string_view, T> ||
469 std::is_same_v<char*, std::decay_t<T>> ||
470 std::is_same_v<const char*, T>) {
471 // String-like types
472 os << symbol_str << t << symbol_str;
473 } else if constexpr (std::is_same_v<signed char, T> ||
474 std::is_same_v<unsigned char, T>) {
475 // Buffer-like types, don't print as char
476 os << static_cast<int>(t);
477 } else if constexpr (std::is_pointer_v<T>) {
478 // Pointer types, don't print char* as string
479 os << static_cast<const void*>(t);
480 } else if constexpr (detail::HasBeginEnd<T>() || std::is_array_v<T>) {
481 // Array-like types
482 os << symbol_begin;
483 Long count = 0;
484 for (auto& value : t) {
485 if (count > 0) {
486 os << symbol_delim;
487 }
488 if (count < limit || limit < 0) {
489 ToString(os, value, symbol_begin, symbol_delim, symbol_end,
490 symbol_str, limit);
491 } else if (count == limit) {
492 os << "...";
493 break;
494 }
495 ++count;
496 }
497 os << symbol_end;
498 } else if constexpr (detail::HasTupleSize<T>()) {
499 // Tuple-like types
500 detail::ToStringTupleImp(std::make_index_sequence<std::tuple_size_v<T>>{},
501 os, t, symbol_begin, symbol_delim, symbol_end,
502 symbol_str, limit);
503 } else {
504 // Scalar types
505 os << t;
506 }
507 return os;
508}
509
510template <class T>
511std::string amrex::ToString(const T& t, const char* symbol_begin, const char* symbol_delim,
512 const char* symbol_end, const char* symbol_str,
513 int limit, std::ostringstream ss)
514{
515 ToString(ss, t, symbol_begin, symbol_delim, symbol_end, symbol_str, limit);
516 return ss.str();
517}
518
519template <typename F, typename... T>
521auto amrex::callNoinline (F const& f, T&&... arg)
522 -> decltype(std::declval<F>()(std::declval<T>()...)) // needed for nvcc
523{
526 return f(std::forward<T>(arg)...);
527 }
528 ))
529 AMREX_IF_ON_DEVICE(( return f(std::forward<T>(arg)...); ))
530}
531
532#endif /*BL_UTILITY_H*/
#define BL_ASSERT(EX)
Definition AMReX_BLassert.H:39
#define AMREX_NO_INLINE
Definition AMReX_Extension.H:136
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
void amrex_free(void *p)
Definition AMReX_Utility.cpp:954
void * amrex_malloc(std::size_t size)
Definition AMReX_Utility.cpp:948
Definition AMReX_Utility.H:172
std::ostream::pos_type spos
Definition AMReX_Utility.H:186
bool TryFileOutput()
Definition AMReX_Utility.cpp:647
int maxTries
Definition AMReX_Utility.H:182
static void ClearStreamErrors()
Definition AMReX_Utility.H:179
std::string fileName
Definition AMReX_Utility.H:184
static int nStreamErrors
Definition AMReX_Utility.H:189
std::string suffix
Definition AMReX_Utility.H:187
bool abortOnRetryFailure
Definition AMReX_Utility.H:183
int tries
Definition AMReX_Utility.H:182
bool TryOutput()
Definition AMReX_Utility.cpp:596
static int NStreamErrors()
Definition AMReX_Utility.H:178
std::ostream * sros
Definition AMReX_Utility.H:185
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
T * dataPtr() noexcept
get access to the underlying data pointer
Definition AMReX_Vector.H:49
Long size() const noexcept
Definition AMReX_Vector.H:53
Definition AMReX_Utility.H:160
friend std::istream & operator>>(std::istream &, const expect &exp)
std::string istr
Definition AMReX_Utility.H:168
const std::string & the_string() const
Definition AMReX_Utility.cpp:568
std::tuple< IntVectND< 3 >, int, Direction, Kind > Key
Definition AMReX_FFT_Helper.H:1201
Definition AMReX_FillPatchUtil_I.H:7
void ToStringTupleImp(std::index_sequence< idx... >, std::ostream &os, const T &t, const char *symbol_begin, const char *symbol_delim, const char *symbol_end, const char *symbol_str, int limit)
Definition AMReX_Utility.H:440
constexpr decltype((std::tuple_size< T >::value, true)) HasTupleSize()
Definition AMReX_Utility.H:430
constexpr decltype((std::declval< T >().begin(), std::declval< T >().end(), true)) HasBeginEnd()
Definition AMReX_Utility.H:420
int MPI_Comm
Definition AMReX_ccse-mpi.H:51
Definition AMReX_Amr.cpp:49
std::ostream & ToString(std::ostream &os, const T &t, const char *symbol_begin="[", const char *symbol_delim=", ", const char *symbol_end="]", const char *symbol_str="\"", int limit=100)
Definition AMReX_Utility.H:463
void SyncStrings(const Vector< std::string > &localStrings, Vector< std::string > &syncedStrings, bool &alreadySynced)
Definition AMReX_Utility.cpp:695
double InvNormDistBest(double p)
This function returns an approximation of the inverse cumulative standard normal distribution functio...
Definition AMReX_Utility.cpp:408
void FileOpenFailed(const std::string &file)
Output a message and abort when couldn't open the file.
Definition AMReX_Utility.cpp:137
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:253
void BroadcastStringArray(Vector< std::string > &bSA, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition AMReX_Utility.cpp:917
__host__ __device__ T arg(const GpuComplex< T > &a_z) noexcept
Return the angle of a complex number's polar representation.
Definition AMReX_GpuComplex.H:402
Vector< std::string > UnSerializeStringArray(const Vector< char > &charArray)
Definition AMReX_Utility.cpp:871
std::conditional_t< std::chrono::high_resolution_clock::is_steady, std::chrono::high_resolution_clock, std::chrono::steady_clock > MaxResSteadyClock
Definition AMReX_Utility.H:218
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:145
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:258
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:940
uint64_t hash_vector(const Vector< T > &vec, uint64_t seed=0xDEADBEEFDEADBEEF) noexcept
Definition AMReX_Utility.H:407
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:167
void CreateDirectoryFailed(const std::string &dir)
Output a message and abort when couldn't create the directory.
Definition AMReX_Utility.cpp:129
void BroadcastArray(Vector< T > &aT, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition AMReX_Utility.H:270
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
__host__ __device__ auto callNoinline(F const &f, T &&... arg) -> decltype(std::declval< F >()(std::declval< T >()...))
Call given function without inline.
Definition AMReX_Utility.H:521
void BroadcastString(std::string &bStr, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition AMReX_Utility.cpp:901
__host__ __device__ GpuComplex< T > exp(const GpuComplex< T > &a_z) noexcept
Complex expotential function.
Definition AMReX_GpuComplex.H:338
Vector< char > SerializeStringArray(const Vector< std::string > &stringArray)
Definition AMReX_Utility.cpp:857
std::istream & operator>>(std::istream &is, BoxND< dim > &bx)
Read from istream.
Definition AMReX_Box.H:1718
void hash_combine(uint64_t &seed, const T &val) noexcept
Definition AMReX_Utility.H:400
int verbose
Definition AMReX_DistributionMapping.cpp:36
void Sleep(double sleepsec)
Definition AMReX_Utility.cpp:931
void UtilRenameDirectoryToOld(const std::string &path, bool callbarrier=true)
Rename a current directory if it exists.
Definition AMReX_Utility.cpp:222
static const Long gcc_map_node_extra_bytes
Definition AMReX_Utility.H:202
double InvNormDist(double p)
This function returns an approximation of the inverse cumulative standard normal distribution functio...
Definition AMReX_Utility.cpp:287
void UtilCreateDirectoryDestructive(const std::string &path, bool callbarrier=true)
Create a new directory, removing old one if it exists.
Definition AMReX_Utility.cpp:196
std::string UniqueString()
Create a (probably) unique string.
Definition AMReX_Utility.cpp:151
void BroadcastBool(bool &bBool, int myLocalId, int rootId, const MPI_Comm &localComm)
Definition AMReX_Utility.cpp:886
void OutOfMemory()
Aborts after printing message indicating out-of-memory; i.e. operator new has failed....
Definition AMReX_Utility.cpp:247
Definition AMReX_TypeTraits.H:99