ParallelFileMerger.hpp
1 /*
2  Copyright 2016 Dr. Blatt - HPC-Simulation-Software & Services
3  Copyright 2016 STATOIL AS.
4 
5  This file is part of the Open Porous Media project (OPM).
6 
7  OPM is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  OPM is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with OPM. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef OPM_PARALLELFILEMERGER_HEADER_INCLUDED
22 #define OPM_PARALLELFILEMERGER_HEADER_INCLUDED
23 
24 #include <memory>
25 #include <iostream>
26 
27 #include <boost/filesystem.hpp>
28 #include <boost/filesystem/fstream.hpp>
29 #include <boost/regex.hpp>
30 
31 namespace Opm
32 {
33 namespace detail
34 {
35 
36 namespace fs = boost::filesystem;
37 
45 {
46 public:
50  ParallelFileMerger(const fs::path& output_dir,
51  const std::string& deckname)
52  : debugFileRegex_("\\."+deckname+"\\.\\d+\\.DEBUG"),
53  logFileRegex_(deckname+"\\.\\d+\\.PRT")
54  {
55  auto debugPath = output_dir;
56  debugPath /= (std::string(".") + deckname + ".DEBUG");
57  debugStream_.reset(new fs::ofstream(debugPath,
58  std::ofstream::app));
59  auto logPath = output_dir;
60  logPath /= ( deckname + ".PRT");
61  logStream_.reset(new fs::ofstream(logPath,
62  std::ofstream::app));
63  }
64 
65  void operator()(const fs::path& file)
66  {
67  const static boost::regex regex(".+\\.(\\d+)\\..+");
68  boost::smatch matches;
69  std::string filename = file.filename().native();
70 
71  if ( boost::regex_match(filename, matches, regex) )
72  {
73  std::string rank = boost::regex_replace(filename, regex, "\\1");
74 
75  if( boost::regex_match(filename, logFileRegex_) )
76  {
77  appendFile(*logStream_, file, rank);
78  }
79  else
80  {
81  if (boost::regex_match(filename, debugFileRegex_) )
82  {
83  appendFile(*debugStream_, file, rank);
84  }
85  else
86  {
87  std::cerr << "WARNING: Unrecognized file with name "
88  << filename
89  << " that might stem from a parallel run."
90  << std::endl;
91  }
92  }
93  }
94  }
95 private:
100  void appendFile(fs::ofstream& of, const fs::path& file, const std::string& rank)
101  {
102  if( fs::file_size(file) )
103  {
104  std::cerr << "WARNING: There has been logging to file "
105  << file.string() <<" by process "
106  << rank << std::endl;
107 
108  fs::ifstream in(file);
109  of<<std::endl<< std::endl;
110  of<<"=======================================================";
111  of<<std::endl<<std::endl;
112  of << " Output written by rank " << rank << " to file " << file.string();
113  of << ":" << std::endl << std::endl;
114  of << in.rdbuf() << std::endl << std::endl;
115  of << "======================== end output =====================";
116  of << std::endl;
117  in.close();
118  }
119  fs::remove(file);
120  }
121 
123  boost::regex debugFileRegex_;
125  boost::regex logFileRegex_;
127  std::unique_ptr<fs::ofstream> debugStream_;
129  std::unique_ptr<fs::ofstream> logStream_;
130 };
131 } // end namespace detail
132 } // end namespace OPM
133 #endif // end header guard
ParallelFileMerger(const fs::path &output_dir, const std::string &deckname)
Constructor.
Definition: ParallelFileMerger.hpp:50
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: AdditionalObjectDeleter.hpp:22
A functor that merges multiple files of a parallel run to one file.
Definition: ParallelFileMerger.hpp:44