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:
182 int tries, maxTries;
183 bool abortOnRetryFailure = true;
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
192 Vector<char> SerializeStringArray(const Vector<std::string> &stringArray);
193 Vector<std::string> UnSerializeStringArray(const Vector<char> &charArray);
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.
203 static const Long gcc_map_node_extra_bytes = 32L;
205 template <typename T> amrex::Long bytesOf (const std::vector<T>& v);
206 template <typename Key, typename T, class Compare> amrex::Long bytesOf (const std::map<Key,T,Compare>& m);
207
208 void BroadcastBool(bool &bBool, int myLocalId, int rootId, const MPI_Comm &localComm);
209
210 void BroadcastString(std::string &bStr, int myLocalId, int rootId, const MPI_Comm &localComm);
211 void BroadcastStringArray(Vector<std::string> &bSA, int myLocalId, int rootId, const MPI_Comm &localComm);
212
213 template<class T> void BroadcastArray(Vector<T> &aT, int myLocalId, int rootId, const MPI_Comm &localComm);
214
215 void Sleep (double sleepsec); // Sleep for sleepsec seconds
216
217
218 using MaxResSteadyClock = std::conditional_t<std::chrono::high_resolution_clock::is_steady,
219 std::chrono::high_resolution_clock,
220 std::chrono::steady_clock>;
221 double second () noexcept;
222
223 template<typename T> void hash_combine (uint64_t & seed, const T & val) noexcept;
224 template<typename T> uint64_t hash_vector (const Vector<T> & vec, uint64_t seed = 0xDEADBEEFDEADBEEF) noexcept;
225
226 template <class T>
227 std::ostream& ToString(std::ostream& os,
228 const T& t,
229 const char* symbol_begin = "[",
230 const char* symbol_delim = ", ",
231 const char* symbol_end = "]",
232 const char* symbol_str = "\"",
233 int limit = 100);
234
235 template <class T>
236 std::string ToString(const T& t,
237 const char* symbol_begin = "[",
238 const char* symbol_delim = ", ",
239 const char* symbol_end = "]",
240 const char* symbol_str = "\"",
241 int limit = 100,
242 std::ostringstream ss = std::ostringstream{});
243
253 template <typename F, typename... T>
255 auto callNoinline (F const& f, T&&... arg)
256 -> decltype(std::declval<F>()(std::declval<T>()...)); // needed for nvcc
257}
258
259template <typename T>
260bool amrex::is_it (std::string const& s, T& v)
261{
262 std::istringstream ss(s);
263 if (ss >> v) {
264 std::string left;
265 std::getline(ss, left);
266 return left.empty();
267 } else {
268 return false;
269 }
270}
271
272template<class T> void amrex::BroadcastArray(Vector<T> &aT, int myLocalId, int rootId, const MPI_Comm &localComm)
273{
274 int aT_Size(-2);
275 if(myLocalId == rootId) {
276 aT_Size = aT.size();
277 }
278 ParallelDescriptor::Bcast(&aT_Size, 1, rootId, localComm);
279 BL_ASSERT(aT_Size >= 0);
280 if(myLocalId != rootId) {
281 aT.resize(aT_Size);
282 }
283 if(aT_Size > 0) {
284 ParallelDescriptor::Bcast(aT.dataPtr(), aT.size(), rootId, localComm);
285 }
286}
287
288
289//
290// I'm going to document right here all the BL macros that aren't documented
291// anywhere else. Note that all these #ifdef ... #endif blocks are necessary
292// to get doc++ to properly document the macros.
293//
294
295#ifdef BL_LANG_FORT
296#undef BL_LANG_FORT
297/*
298 The macro BL_LANG_FORT indicates that Fortran code is being compiled.
299*/
300#define BL_LANG_FORT 1
301#endif /*BL_LANG_FORT*/
302
303#ifdef BL_FORT_USE_UNDERSCORE
304#undef BL_FORT_USE_UNDERSCORE
305/*
306 The macro BL_FORT_USE_UNDERSCORE indicates that C++ code should call
307 Fortran routines by appending an underscore to the name of the Fortran
308 routine. This is set automatically by the make subsystem.
309
310 For example, if the Fortran routine is named abcxyx, then it will
311 be called in C++ code as abcxyz_.
312*/
313#define BL_FORT_USE_UNDERSCORE 1
314#endif /*BL_FORT_USE_UNDERSCORE*/
315
316#ifdef BL_FORT_USE_UPPERCASE
317#undef BL_FORT_USE_UPPERCASE
318/*
319 The macro BL_FORT_USE_UPPERCASE indicates that C++ code should call
320 Fortran routines using uppercase letters for all the letters in the
321 routine. This is set automatically by the make subsystem.
322
323 For example, if the Fortran routine is named abcxyx, then it will
324 be called in C++ code as ABCXYZ.
325*/
326#define BL_FORT_USE_UPPERCASE 1
327#endif /*BL_FORT_USE_UPPERCASE*/
328
329#ifdef BL_FORT_USE_LOWERCASE
330#undef BL_FORT_USE_LOWERCASE
331/*
332 The macro BL_FORT_USE_LOWERCASE indicates that C++ code should call
333 Fortran routines using lowercase letters for all the letters in the
334 routine. This is set automatically by the make subsystem.
335
336 For example, if the Fortran routine is named abcxyx, then it will
337 be called in C++ code as abcxyx.
338*/
339#define BL_FORT_USE_LOWERCASE 1
340#endif /*BL_FORT_USE_LOWERCASE*/
341
342/*
343 BL_IGNORE_MAX is a macro that expands to the literal value 100000. It is
344 defined when compiling either Fortran or C++ code; i.e. when either
345 BL_LANG_CC or BL_LANG_FORT is defined. It is used in calls to
346 istream::ignore() in the AMReX code when reading in characters from an
347 istream. We use this macro instead of the more proper INT_MAX from
348 <limits> since at least one compiler didn't work properly when
349 istream::ignore() was passed INT_MAX.
350*/
351#define BL_IGNORE_MAX 100000
352
353template <typename T>
355amrex::bytesOf (const std::vector<T>& v)
356{
357 return sizeof(v) + v.capacity()*sizeof(T);
358}
359
360template <typename Key, typename T, class Compare>
362amrex::bytesOf (const std::map<Key,T,Compare>& m)
363{
364 return sizeof(m) + m.size()*(sizeof(Key)+sizeof(T)+gcc_map_node_extra_bytes);
365}
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
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}
462
463template <class T>
464std::ostream& amrex::ToString(std::ostream& os, const T& t, const char* symbol_begin,
465 const char* symbol_delim, const char* symbol_end,
466 const char* symbol_str, int limit)
467{
468 if constexpr (std::is_same_v<std::string, T> ||
469 std::is_same_v<std::string_view, T> ||
470 std::is_same_v<char*, std::decay_t<T>> ||
471 std::is_same_v<const char*, T>) {
472 // String-like types
473 os << symbol_str << t << symbol_str;
474 } else if constexpr (std::is_same_v<signed char, T> ||
475 std::is_same_v<unsigned char, T>) {
476 // Buffer-like types, don't print as char
477 os << static_cast<int>(t);
478 } else if constexpr (std::is_pointer_v<T>) {
479 // Pointer types, don't print char* as string
480 os << static_cast<const void*>(t);
481 } else if constexpr (detail::HasBeginEnd<T>() || std::is_array_v<T>) {
482 // Array-like types
483 os << symbol_begin;
484 Long count = 0;
485 for (auto& value : t) {
486 if (count > 0) {
487 os << symbol_delim;
488 }
489 if (count < limit || limit < 0) {
490 ToString(os, value, symbol_begin, symbol_delim, symbol_end,
491 symbol_str, limit);
492 } else if (count == limit) {
493 os << "...";
494 break;
495 }
496 ++count;
497 }
498 os << symbol_end;
499 } else if constexpr (detail::HasTupleSize<T>()) {
500 // Tuple-like types
501 detail::ToStringTupleImp(std::make_index_sequence<std::tuple_size_v<T>>{},
502 os, t, symbol_begin, symbol_delim, symbol_end,
503 symbol_str, limit);
504 } else {
505 // Scalar types
506 os << t;
507 }
508 return os;
509}
510
511template <class T>
512std::string amrex::ToString(const T& t, const char* symbol_begin, const char* symbol_delim,
513 const char* symbol_end, const char* symbol_str,
514 int limit, std::ostringstream ss)
515{
516 ToString(ss, t, symbol_begin, symbol_delim, symbol_end, symbol_str, limit);
517 return ss.str();
518}
519
520template <typename F, typename... T>
522auto amrex::callNoinline (F const& f, T&&... arg)
523 -> decltype(std::declval<F>()(std::declval<T>()...)) // needed for nvcc
524{
527 return f(std::forward<T>(arg)...);
528 }
529 ))
530 AMREX_IF_ON_DEVICE(( return f(std::forward<T>(arg)...); ))
531}
532
533#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
bool TryFileOutput()
Definition AMReX_Utility.cpp:647
static void ClearStreamErrors()
Definition AMReX_Utility.H:179
bool TryOutput()
Definition AMReX_Utility.cpp:596
static int NStreamErrors()
Definition AMReX_Utility.H:178
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)
const std::string & the_string() const
Definition AMReX_Utility.cpp:568
amrex_long Long
Definition AMReX_INT.H:30
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:464
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:403
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:220
amrex::Long bytesOf(const std::vector< T > &v)
Definition AMReX_Utility.H:355
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:260
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
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:272
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:522
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:339
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:1825
void hash_combine(uint64_t &seed, const T &val) noexcept
Definition AMReX_Utility.H:400
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
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