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