Alamo
Util.cpp
Go to the documentation of this file.
1 #include "Util.H"
2 #include "Color.H"
3 
4 #include <chrono>
5 #include <filesystem>
6 
7 #include "AMReX_ParallelDescriptor.H"
8 #include "AMReX_Utility.H"
9 
10 #include "IO/ParmParse.H"
11 #include "IO/WriteMetaData.H"
12 #include "IO/FileNameParse.H"
13 #include "Color.H"
14 #include "Numeric/Stencil.H"
15 
16 namespace Util
17 {
18 
19 std::string filename = "";
20 std::pair<std::string,std::string> file_overwrite;
21 
22 std::string GetFileName()
23 {
24  if (filename == "")
25  {
26  IO::ParmParse pp;
27  IO::ParmParse pp_amr("amr");
28 
29  if (pp_amr.contains("plot_file") && pp.contains("plot_file"))
30  Util::Abort("plot_file specified in too many locations");
31  else if (pp_amr.contains("plot_file"))
32  {
33  if (amrex::ParallelDescriptor::IOProcessor())
34  amrex::Warning("amr.plot_file will be depricated; use plot_file instead");
35  pp_amr.query("plot_file", filename);
36 
37  }
38  else if (pp.contains("plot_file"))
39  {
40  pp_query("plot_file", filename); // Name of directory containing all output data
41  }
43  // else
44  // if (amrex::ParallelDescriptor::IOProcessor())
45  // Util::Abort("No plot file specified! (Specify plot_file = \"plot_file_name\" in input file");
46  }
47  return filename;
48 }
49 void CopyFileToOutputDir(std::string a_path, bool fullpath, std::string prefix)
50 {
51  try
52  {
53  if (filename == "")
54  Util::Exception(INFO,"Cannot back up files yet because the output directory has not been specified");
55 
56  std::string basefilename = std::filesystem::path(a_path).filename();
57  std::string absolutepath = std::filesystem::absolute(std::filesystem::path(a_path)).string();
58  std::string abspathfilename = absolutepath;
59  std::replace(abspathfilename.begin(),abspathfilename.end(),'/','_');
60  if (prefix != "")
61  {
62  abspathfilename = prefix + "__" + abspathfilename;
63  basefilename = prefix + "__" + abspathfilename;
64  }
65 
66  if (amrex::ParallelDescriptor::IOProcessor())
67  {
68  std::string destinationpath;
69  if (fullpath) destinationpath = filename+"/"+abspathfilename;
70  else destinationpath = filename+"/"+basefilename;
71 
72  // Copy the file where the file name is the absolute path, with / replaced with _
73  if (std::filesystem::exists(destinationpath))
74  Util::Exception(INFO,"Trying to copy ",destinationpath," but it already exists.");
75  std::filesystem::copy_file(a_path,destinationpath);
76  }
77  }
78  catch (std::filesystem::filesystem_error const& ex)
79  {
81  "file system error: \n",
82  " what(): " , ex.what() , '\n',
83  " path1(): " , ex.path1() , '\n',
84  " path2(): " , ex.path2() , '\n',
85  " code().value(): " , ex.code().value() , '\n',
86  " code().message(): " , ex.code().message() , '\n',
87  " code().category(): " , ex.code().category().name());
88  }
89 }
90 
91 std::pair<std::string,std::string> GetOverwrittenFile()
92 {
93  return file_overwrite;
94 }
95 
96 void SignalHandler(int s)
97 {
98  if (amrex::ParallelDescriptor::IOProcessor())
99  {
100  std::string filename = GetFileName();
102  if (s == SIGSEGV) status = IO::Status::Segfault;
103  else if (s == SIGINT) status = IO::Status::Interrupt;
104  if (s == SIGABRT) status = IO::Status::Abort;
105  if (filename != "")
106  IO::WriteMetaData(filename,status);
107  }
108 
109 #ifdef MEME
110  IO::ParmParse pp;
111  if (!pp.contains("nomeme"))
112  {
113  time_t timer; time(&timer);
114  std::stringstream cmd;
115  cmd << "xdg-open " << BUILD_DIR << "/src/Util/Meme/cat0" << (1+((int)timer)%6) << ".gif &";
116  std::system(cmd.str().c_str());
117  std::cout << Color::Bold << Color::FG::Red << "PROGRAM FAILED!" << Color::Reset << " (Compile without -DMEME, or set nomeme = 1 in the input file to disable this!)";
118  }
119 #endif
120 
121  amrex::BLBackTrace::handler(s);
122 }
123 
124 
125 void Initialize ()
126 {
127  int argc = 0;
128  char **argv = nullptr;
129  Initialize(argc,argv);
130 }
131 void Initialize (int argc, char* argv[])
132 {
133  srand (time(NULL));
134 
135  amrex::Initialize(argc, argv);
136 
137  IO::ParmParse pp_amrex("amrex");
138  pp_amrex.add("throw_exception",1);
139  //amrex.throw_exception=1
140 
141  signal(SIGSEGV, Util::SignalHandler);
142  signal(SIGINT, Util::SignalHandler);
143  signal(SIGABRT, Util::SignalHandler);
144 
145  std::string filename = GetFileName();
146 
147  if (amrex::ParallelDescriptor::IOProcessor() && filename != "")
148  {
151  }
152 }
153 
154 void Finalize()
155 {
156  std::string filename = GetFileName();
157  if (filename != "")
159  amrex::Finalize();
160 }
161 
162 
163 
164 void
165 Abort (const char * msg) { Terminate(msg, SIGABRT, true); }
166 
167 void
168 Terminate(const char * /* msg */, int signal, bool /*backtrace*/)
169 {
170  SignalHandler(signal);
171 }
172 
173 std::pair<std::string,std::string>
174 CreateCleanDirectory (const std::string &path, bool callbarrier)
175 {
176  std::pair<std::string,std::string> ret("","");
177 
178  if(amrex::ParallelDescriptor::IOProcessor()) {
179  if(amrex::FileExists(path)) {
180  std::time_t t = std::time(0);
181  std::tm * now = std::localtime(&t);
182  int year = now->tm_year+1900;
183  int month = now->tm_mon+1;
184  int day = now->tm_mday;
185  int hour = now->tm_hour;
186  int minute = now->tm_min;
187  int second = now->tm_sec;
188 
189  std::stringstream ss;
190  ss << year
191  << std::setfill('0') << std::setw(2) << month
192  << std::setfill('0') << std::setw(2) << day
193  << std::setfill('0') << std::setw(2) << hour
194  << std::setfill('0') << std::setw(2) << minute
195  << std::setfill('0') << std::setw(2) << second;
196 
197  std::string newoldname(path + ".old." + ss.str());
198  if (amrex::system::verbose) {
199  amrex::Print() << "Util::CreateCleanDirectory(): " << path
200  << " exists. Renaming to: " << newoldname << std::endl;
201  }
202  std::rename(path.c_str(), newoldname.c_str());
203  ret.first = path;
204  ret.second = newoldname;
205  }
206  if( ! amrex::UtilCreateDirectory(path, 0755)) {
207  amrex::CreateDirectoryFailed(path);
208  }
209  }
210  if(callbarrier) {
211  // Force other processors to wait until directory is built.
212  amrex::ParallelDescriptor::Barrier("amrex::UtilCreateCleanDirectory");
213  }
214  return ret;
215 }
216 
217 
218 
219 
220 
221 
222 namespace String
223 {
224 int ReplaceAll(std::string &str, const std::string before, const std::string after)
225 {
226  size_t start_pos = 0;
227  while((start_pos = str.find(before, start_pos)) != std::string::npos) {
228  str.replace(start_pos, before.length(), after);
229  start_pos += after.length();
230  }
231  return 0;
232 }
233 int ReplaceAll(std::string &str, const char before, const std::string after)
234 {
235  size_t start_pos = 0;
236  while((start_pos = str.find(before, start_pos)) != std::string::npos) {
237  str.replace(start_pos, 1, after);
238  start_pos += after.length();
239  }
240  return 0;
241 }
242 
243 std::string Join(std::vector<std::string> & vec, char separator)
244 {
245  std::ostringstream oss;
246  for (size_t i = 0; i < vec.size(); ++i) {
247  oss << vec[i];
248  if (i < vec.size() - 1) { // Don't add separator after the last element
249  oss << separator;
250  }
251  }
252  return oss.str();
253 }
254 
255 std::string Wrap(std::string text, unsigned per_line)
256 {
257  unsigned line_begin = 0;
258 
259  while (line_begin < text.size())
260  {
261  const unsigned ideal_end = line_begin + per_line ;
262  unsigned line_end = ideal_end <= text.size() ? ideal_end : text.size()-1;
263 
264  if (line_end == text.size() - 1)
265  ++line_end;
266  else if (std::isspace(text[line_end]))
267  {
268  text[line_end] = '\n';
269  ++line_end;
270  }
271  else // backtrack
272  {
273  unsigned end = line_end;
274  while ( end > line_begin && !std::isspace(text[end]))
275  --end;
276 
277  if (end != line_begin)
278  {
279  line_end = end;
280  text[line_end++] = '\n';
281  }
282  else
283  text.insert(line_end++, 1, '\n');
284  }
285 
286  line_begin = line_end;
287  }
288 
289  return text;
290 }
291 std::vector<std::string> Split(std::string &str, const char delim)
292 {
293  std::vector<std::string> ret;
294  std::stringstream ss(str);
295  std::string item;
296  while (std::getline(ss, item, delim)) {
297  ret.push_back(item);
298  }
299  return ret;
300 }
301 bool Contains(std::string &str, const std::string find)
302 {
303  if (str.find(find) != std::string::npos) return true;
304  else return false;
305 }
306 
307 template<>
308 std::complex<int> Parse(std::string input)
309 {
310  int re=0, im=0;
311 
312  ReplaceAll(input, "+", " +");
313  ReplaceAll(input, "-", " -");
314  std::vector<std::string> tokens = Split(input,' ');
315  for (unsigned int i = 0; i < tokens.size(); i++)
316  {
317  if(tokens[i]=="") continue;
318  if(Contains(tokens[i],"i"))
319  {
320  ReplaceAll(tokens[i],"i","");
321  im += std::stoi(tokens[i]);
322  }
323  else
324  {
325  re += std::stoi(tokens[i]);
326  }
327  }
328  return std::complex<int>(re,im);
329 }
330 
331 
332 }
333 
334 
335 namespace Test
336 {
337 int Message(std::string testname)
338 {
339  if (amrex::ParallelDescriptor::IOProcessor())
340  std::cout << std::left
341  << Color::FG::White << Color::Bold << testname << Color::Reset << std::endl;
342  return 0;
343 }
344 int Message(std::string testname, int failed)
345 {
346  if (amrex::ParallelDescriptor::IOProcessor())
347  {
348  winsize w;
349  ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
350  std::stringstream ss;
351  if (!failed)
352  ss << "[" << Color::FG::Green << Color::Bold << "PASS" << Color::Reset << "]";
353  else
354  ss << "[" << Color::FG::Red << Color::Bold << "FAIL" << Color::Reset << "]";
355 
356  int terminalwidth = 80; //std::min(w.ws_col,(short unsigned int) 100);
357 
358  std::cout << std::left
359  << testname
360  << std::setw(terminalwidth - testname.size() + ss.str().size() - 6) << std::right << std::setfill('.') << ss.str() << std::endl;
361  }
362  return failed;
363 }
364 int SubMessage(std::string testname, int failed)
365 {
366  if (amrex::ParallelDescriptor::IOProcessor())
367  {
368  winsize w;
369  ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
370  std::stringstream ss;
371  if (!failed)
372  ss << "[" << Color::FG::LightGreen << Color::Bold << "PASS" << Color::Reset << "]";
373  else
374  ss << "[" << Color::FG::Red << Color::Bold << "FAIL" << Color::Reset << "]";
375 
376  int terminalwidth = 80;
377 
378  std::cout << std::left
379  << " ├ "
380  << testname
381  << std::setw(terminalwidth - testname.size() + ss.str().size() - 12) << std::right << std::setfill('.') << ss.str() << std::endl;
382  }
383  return failed;
384 }
385 int SubFinalMessage(int failed)
386 {
387  if (amrex::ParallelDescriptor::IOProcessor())
388  {
389  winsize w;
390  ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
391  std::stringstream ss;
392  std::cout << std::left << " └ ";
393 
394  if (!failed)
395  std::cout << Color::FG::Green << Color::Bold << failed << " tests failed" << Color::Reset << std::endl;
396  else
397  std::cout << Color::FG::Red << Color::Bold << failed << " tests failed" << Color::Reset << std::endl;
398  }
399  return failed;
400 }
401 
402 }
403 
404 void AverageCellcenterToNode(amrex::MultiFab& node_mf, const int &dcomp, const amrex::MultiFab &cell_mf, const int &scomp, const int &ncomp/*, const int ngrow=0*/)
405 {
406  Util::Assert(INFO,TEST(dcomp + ncomp <= node_mf.nComp()));
407  Util::Assert(INFO,TEST(scomp + ncomp <= cell_mf.nComp()));
408  //Util::Assert(INFO,TEST(cell_mf.boxArray() == node_mf.boxArray()));
409  Util::Assert(INFO,TEST(cell_mf.DistributionMap() == cell_mf.DistributionMap()));
410  Util::Assert(INFO,TEST(cell_mf.nGrow() > 0));
411  for (amrex::MFIter mfi(node_mf,amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
412  {
413  amrex::Box bx = mfi.nodaltilebox();
414  amrex::Array4<Set::Scalar> const& node = node_mf.array(mfi);
415  amrex::Array4<const Set::Scalar> const& cell = cell_mf.array(mfi);
416  for (int n = 0; n < ncomp; n++)
417  amrex::ParallelFor (bx,[=] AMREX_GPU_DEVICE(int i, int j, int k) {
418  node(i,j,k,dcomp+n) = Numeric::Interpolate::CellToNodeAverage(cell,i,j,k,scomp+n);
419  });
420  }
421 }
422 
423 
424 }
IO::WriteMetaData
void WriteMetaData(std::string plot_file, Status status, int per)
Definition: WriteMetaData.cpp:17
Util::filename
std::string filename
Definition: Util.cpp:19
Util::Initialize
void Initialize()
Definition: Util.cpp:125
Numeric::Interpolate::CellToNodeAverage
static AMREX_FORCE_INLINE T CellToNodeAverage(const amrex::Array4< const T > &f, const int &i, const int &j, const int &k, const int &m, std::array< StencilType, AMREX_SPACEDIM > stencil=DefaultType)
Definition: Stencil.H:1256
Util::String::Parse
std::complex< int > Parse(std::string input)
Definition: Util.cpp:308
Util::GetFileName
std::string GetFileName()
Definition: Util.cpp:22
FileNameParse.H
Util::Test::Message
int Message(std::string testname)
Definition: Util.cpp:337
Color::FG::Red
static std::string Red
Definition: Color.H:20
Util.H
Util::AverageCellcenterToNode
void AverageCellcenterToNode(amrex::MultiFab &node_mf, const int &dcomp, const amrex::MultiFab &cell_mf, const int &scomp, const int &ncomp)
Definition: Util.cpp:404
IO::FileNameParse
void FileNameParse(std::string &filename)
Definition: FileNameParse.cpp:14
TEST
#define TEST(x)
Definition: Util.H:21
Util::String::Split
std::vector< std::string > Split(std::string &str, const char delim)
Definition: Util.cpp:291
Color::FG::White
static std::string White
Definition: Color.H:34
Util::String::ReplaceAll
int ReplaceAll(std::string &str, const std::string before, const std::string after)
Definition: Util.cpp:224
t
std::time_t t
Definition: FileNameParse.cpp:12
Util::CreateCleanDirectory
std::pair< std::string, std::string > CreateCleanDirectory(const std::string &path, bool callbarrier)
Definition: Util.cpp:174
ParmParse.H
pp_query
#define pp_query(...)
Definition: ParmParse.H:104
Util::file_overwrite
std::pair< std::string, std::string > file_overwrite
Definition: Util.cpp:20
Util
A collection of utility routines.
Definition: Set.cpp:7
IO::Running
@ Running
Definition: WriteMetaData.H:30
Util::Finalize
void Finalize()
Definition: Util.cpp:154
Util::Terminate
void Terminate(const char *, int signal, bool)
Definition: Util.cpp:168
Color::FG::Green
static std::string Green
Definition: Color.H:21
Util::Test::SubFinalMessage
int SubFinalMessage(int failed)
Definition: Util.cpp:385
Color::FG::LightGreen
static std::string LightGreen
Definition: Color.H:29
IO::Segfault
@ Segfault
Definition: WriteMetaData.H:32
Util::GetOverwrittenFile
std::pair< std::string, std::string > GetOverwrittenFile()
Definition: Util.cpp:91
IO::Complete
@ Complete
Definition: WriteMetaData.H:31
Util::Exception
void Exception(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:194
IO::Interrupt
@ Interrupt
Definition: WriteMetaData.H:33
IO::ParmParse::contains
bool contains(std::string name)
Definition: ParmParse.H:151
Util::Assert
AMREX_FORCE_INLINE void Assert(std::string file, std::string func, int line, std::string smt, bool pass, Args const &... args)
Definition: Util.H:65
Color::Bold
static std::string Bold
Definition: Color.H:9
Util::Abort
void Abort(const char *msg)
Definition: Util.cpp:165
IO::Status
Status
Definition: WriteMetaData.H:29
Color::Reset
static std::string Reset
Definition: Color.H:8
Util::String::Wrap
std::string Wrap(std::string text, unsigned per_line)
Definition: Util.cpp:255
WriteMetaData.H
Util::SignalHandler
void SignalHandler(int s)
Definition: Util.cpp:96
Util::Warning
void Warning(std::string file, std::string func, int line, Args const &... args)
Definition: Util.H:171
IO::ParmParse
Definition: ParmParse.H:110
Util::CopyFileToOutputDir
void CopyFileToOutputDir(std::string a_path, bool fullpath, std::string prefix)
Definition: Util.cpp:49
Util::Test::SubMessage
int SubMessage(std::string testname, int failed)
Definition: Util.cpp:364
Test
Definition: GB.H:7
Util::String::Contains
bool Contains(std::string &str, const std::string find)
Definition: Util.cpp:301
Util::Initialize
void Initialize(int argc, char *argv[])
Definition: Util.cpp:131
Util::String::Join
std::string Join(std::vector< std::string > &vec, char separator)
Definition: Util.cpp:243
INFO
#define INFO
Definition: Util.H:20
Color.H