8 #include <boost/chrono.hpp>
9 #include <boost/filesystem.hpp>
10 #include <boost/program_options.hpp>
18 using namespace OpenMPCD;
20 static const char*
const defaultConfigPath=
"./config.txt";
23 static const std::string getCurrentDateTimeString()
25 char datetimeString[512];
26 const time_t datetime=std::time(0);
27 struct tm* datetimeTM=localtime(&datetime);
31 if(strftime(datetimeString,
sizeof(datetimeString),
"%F_%T", datetimeTM)==0)
34 return datetimeString;
37 static void createRundir(
38 std::string*
const rundir_ptr, std::string*
const configPath_ptr)
40 std::string& rundir=*rundir_ptr;
45 rundir+=getCurrentDateTimeString();
48 if(boost::filesystem::exists(rundir))
50 typedef boost::filesystem::directory_iterator DI;
51 for(DI it(rundir); it != DI(); ++it)
53 if(it->path().filename() ==
"config.txt")
55 *configPath_ptr = it->path().string();
57 else if(it->path().filename() ==
"input")
68 if(!boost::filesystem::create_directory(rundir))
75 static bool terminateProgram =
false;
76 static bool earlySave =
false;
78 #ifdef OPENMPCD_PLATFORM_POSIX
79 static void signalHandler(
int signum)
90 std::cout <<
"Multiple termination signals caught. "
91 "Aborting execution.\n";
96 terminateProgram =
true;
97 std::cout <<
"Termination signal caught. "
98 "The simulation will gracefully end after the "
105 std::cout<<
"Triggered early save..."<<std::flush;
111 static void installSignalHandler()
113 #ifdef OPENMPCD_PLATFORM_POSIX
114 struct sigaction signalAction;
116 signalAction.sa_handler = &signalHandler;
117 signalAction.sa_flags = 0;
118 if(sigemptyset(&signalAction.sa_mask)!=0)
122 "Failed to install signal handlers (sigemptyset). Aborting.\n");
126 ret+=sigaction(SIGHUP, &signalAction, NULL);
127 ret+=sigaction(SIGINT, &signalAction, NULL);
128 ret+=sigaction(SIGTERM, &signalAction, NULL);
129 ret+=sigaction(SIGUSR1, &signalAction, NULL);
134 "Failed to install signal handlers (sigaction). Aborting.\n");
139 static unsigned int generateSeed()
141 const unsigned int seed_1 = std::time(0);
142 const unsigned int seed_2 =
143 boost::chrono::duration_cast<boost::chrono::nanoseconds>(
144 boost::chrono::high_resolution_clock::now().time_since_epoch()
147 return seed_1 + seed_2;
150 static void run(
const unsigned int maxRuntime, std::string rundir)
152 installSignalHandler();
155 std::string configPath = defaultConfigPath;
156 createRundir(&rundir, &configPath);
159 const unsigned int rngSeed = generateSeed();
163 instrumentation.setAutosave(rundir);
167 const unsigned int sweepCount = config.
read<
unsigned int>(
"mpc.sweeps");
169 const time_t startTime = std::time(0);
173 for(
unsigned int i=0; i<sweepCount; ++i)
177 if(std::time(0) - startTime > maxRuntime)
179 std::cout<<
"Runtime limit has been reached. Terminating.\n";
186 std::cout<<
"Terminating prematurely.\n";
196 const std::string earlyRundir = rundir +
"/EarlySave_" + getCurrentDateTimeString();
198 if(!boost::filesystem::create_directory(earlyRundir))
201 instrumentation.save(earlyRundir);
202 std::cout<<
" done\n"<<std::flush;
206 std::cerr<<
"\n\n\t*** non-fatal exception ***\n";
207 std::cerr<<
"Encountered during early save:\n";
214 instrumentation.measure();
217 std::cout<<
"Done with sweep "<<i<<
"\n";
221 int main(
int argc,
char** argv)
225 namespace BPO = boost::program_options;
226 namespace BPOS = BPO::command_line_style;
228 unsigned int maxRuntime;
231 BPO::options_description cmdLineDesc(
"Supported command line options");
232 cmdLineDesc.add_options()
233 (
"help",
"Print help message.")
234 (
"maxRuntime", BPO::value<unsigned int>(&maxRuntime)->default_value(0),
235 "The maximum (wall-time) runtime of the program, in seconds. 0 for no limit.")
236 (
"rundir", BPO::value<std::string>(&rundir),
237 "Specify the directory to save the run data in. If the "
238 "directory does not exist, it will be created. If it does "
239 "exist, it may at most contain the file `config.txt`, which "
240 "then will be used as the input configuration file, and "
241 "the directory may also contain an entry named `input`.");
243 const BPO::positional_options_description positionalOptions;
245 BPO::variables_map cmdLineVariables;
247 BPO::command_line_parser(argc, argv).
248 options(cmdLineDesc).
249 positional(positionalOptions).
252 BPOS::allow_dash_for_short |
253 BPOS::short_allow_next |
255 BPOS::long_allow_adjacent
259 BPO::notify(cmdLineVariables);
261 if(cmdLineVariables.count(
"help"))
263 std::cout << cmdLineDesc <<
"\n";
270 std::cout<<
"Running for at most "<<maxRuntime<<
" seconds.\n";
274 std::cout<<
"No runtime bound specified.\n";
277 run(maxRuntime, rundir);
281 std::cerr<<
"\n\n\t*** EXCEPTION ***\n";
286 catch(
const boost::program_options::error& e)
288 std::cerr<<
"\n\n\t*** EXCEPTION (boost::program_options::error) ***\n";
291 std::cerr<<
"Try invoking this program with the `--help` option.";
294 catch(
const std::exception& e)
296 std::cerr<<
"\n\n\t*** EXCEPTION (std::exception) ***\n";
303 std::cerr<<
"\n\n\t*** UNKNOWN EXCEPTION ***\n";