← Documentation
ADS-IDAC Engine 5.0.0
Scheduler.cpp
Go to the documentation of this file.
1// Scheduler.cpp: implementation of the Scheduler class.
2//
4
5#include <sstream>
6#include "Scheduler.h"
7#include "../System/SystemModule.h"
9#include "../Branch/BranchRecord.h"
11#include <boost/program_options.hpp>
12#include <cstdlib>
13#include "../Global/ConfigFingerprint.h"
14#include <filesystem>
15namespace fs = std::filesystem;
16#include "VersionConfig.h"
17#include <boost/serialization/export.hpp>
18#include "../Global/SimulationContext.h"
19// #include "..\ADSNetCltDlg.h"
20#include <boost/archive/binary_oarchive.hpp>
21#include <boost/archive/binary_iarchive.hpp>
22BOOST_CLASS_EXPORT_IMPLEMENT(Scheduler)
23using namespace std;
24
25extern std::string notify_ntfy_topic;
26extern std::string notify_discord_webhook;
27std::string auto_ntfy_topic(); // from Notification.cpp
28
29namespace po = boost::program_options;
30
31//extern SystemModule plant;
32
33// #ifndef _CONSOLE
34// extern CString theStrWorkingDir;
35// // the following global variables are for network version only
36// extern CADSNetCltDlg *theCltDlg;
37
38// extern CEvent g_eventPENode;
39// extern CEvent g_eventESNode;
40// extern CEvent g_eventClusterNode;
41
42// #endif
43
44inline char separator() {
45#if defined _WIN32
46 return '//';
47#else
48 return '/';
49#endif
50}
51
54}
55
57}
58
59void Scheduler::parseOptions(int argc, char* argv[]) {
60 // ANSI escape codes for colors
61 const std::string RED = "\033[31m";
62 const std::string GREEN = "\033[32m";
63 const std::string MAGENTA = "\033[35m";
64 const std::string UNDERLINE = "\033[4m";
65 const std::string RESET = "\033[0m";
66
67 string str1;
68 const std::string VERSION_STRING = "v" + std::to_string(ADSIDAC_VERSION_MAJOR) + "." + std::to_string(ADSIDAC_VERSION_MINOR) + "." + std::to_string(ADSIDAC_VERSION_PATCH);
69
70 po::options_description desc("Allowed options");
71 desc.add_options()
72 ("help,h", "produce help message")
73 ("version,v", "display version information")
74 ("info,i", "display detailed information about the application")
75 ("project-dir", po::value<std::string>()->required(), "set project directory")
76 ("input-deck", po::value<std::string>()->required(), "set input deck file")
77 ("solver", po::value<std::string>()->default_value("relap"), "solver backend: relap|0 (default) or mock|1 (REST API mock solver)")
78 ("solver-port", po::value<int>()->default_value(9090), "mock solver port (default 9090)")
79 ("solver-url", po::value<std::string>()->default_value(""), "override mock solver URL (e.g., http://remote-host:8080)")
80 ("no-thermo-cache", po::bool_switch()->default_value(false), "disable thermodynamic table caching (reload from file every sequence)")
81 ("no-memory-restart", po::bool_switch()->default_value(false), "disable in-memory restart (use file-based restart)")
82 ("memory-limit", po::value<long>()->default_value(0), "RSS limit in MB for adaptive restart (0=unlimited)")
83 ("compress-queue", po::bool_switch()->default_value(false), "LZ4-compress restart buffers on MPI server queue")
84 ("aggregate-pe", po::bool_switch()->default_value(false), "write PE nodes as records in a single file per rank instead of one file each (default off: changes output layout)")
85 ("viz-port", po::value<int>()->default_value(0), "Port for real-time DET visualization web server (MPI only, 0=disabled)")
86 ("viz-outputs", po::value<std::string>()->default_value(""), "Output types streamed to viz server: events,es,all (requires --viz-port)")
87 ("notify-ntfy", po::value<std::string>()->implicit_value("auto"), "Send ntfy.sh notification (auto-generates topic from hostname, or specify topic)")
88 ("notify-discord", po::value<std::string>(), "Send completion notification to Discord webhook URL")
89 ("checkpoint-dir", po::value<std::string>()->default_value(""), "directory for DET checkpoint files")
90 ("checkpoint-interval", po::value<int>()->default_value(0), "checkpoint every N sequences (0=disabled)")
91 ("checkpoint-stop", po::bool_switch()->default_value(false), "exit after writing checkpoint (for testing)")
92 ("resume", po::value<std::string>()->default_value(""), "resume simulation from checkpoint file")
93 ("truncation-time", po::value<double>()->default_value(0), "override truncation time from ZCtrlPar.txt (0=use file value)")
94 ("occupancy-log", po::value<std::string>()->default_value(""), "MPI only: append server queue depth and busy-worker count to a CSV on every change (empty=disabled)")
95 ("merge", po::value<std::string>()->default_value("now"), "MPI output merge mode: now (default, rename-based worker-parallel), serial (legacy rank-0 copy loop), or defer (end at tree completion, consolidate later with --merge-only)")
96 ("merge-only", po::bool_switch()->default_value(false), "consolidate the per-rank outputs of a deferred (or interrupted) merge into Output/ and exit; run without mpirun")
97 ("merge-threads", po::value<int>()->default_value(0), "thread pool size for --merge-only rank-directory moves (0 = min(8, hardware))")
98 ("enable-rm-cycle", po::bool_switch()->default_value(false), "enable ReasonMachine snapshot/restore/serialize machinery (dormant cycle; see docs)");
99
100 // Create a variables map
101 po::variables_map vm;
102 try {
103 po::store(po::parse_command_line(argc, argv, desc), vm);
104
105 if (vm.count("help")) {
106 std::cout << desc << "\n";
107 exit(0);
108 }
109
110 if (vm.count("version")) {
111 std::cout << VERSION_STRING << std::endl;
112 exit(0);
113 }
114
115 if (vm.count("info")) {
116 std::cout << "ADS-IDAC\n" << std::endl;
117 std::cout << "Accident Dynamics Simulator paired with the Information, Decision, and Action in a Crew" << std::endl;
118 std::cout << VERSION_STRING << std::endl;
119 std::cout << "Maintained by: Probabilistic Risk Assessment Group of NC State Nuclear Engineering" << std::endl;
120 std::cout << "https://www.ne.ncsu.edu/prag/" << std::endl;
121 exit(0);
122 }
123
124 // Read options from file, if exists
125 std::ifstream ifs("ZiniADS.txt");
126 if (ifs) {
127 po::store(po::parse_config_file(ifs, desc), vm);
128 }
129
130 po::notify(vm);
131 } catch (const po::error &e) {
132 std::cerr << RED <<"ERROR: " << RESET << e.what() << RESET << std::endl;
133 std::cerr << "Check " << GREEN << "./adsidac --help" << RESET <<std::endl;
134 exit(1);
135 }
136
137 // Update class members with parsed values (resolve to absolute paths for MPI rank cd)
138 project_directory = fs::absolute(vm["project-dir"].as<std::string>()).string();
139 input_deck_file_directory_and_name = fs::absolute(vm["input-deck"].as<std::string>()).string();
140
141 // Solver selection: --solver=relap|0|mock|1, --solver-port, --solver-url
142 std::string solver_arg = vm["solver"].as<std::string>();
143 solver_port_ = vm["solver-port"].as<int>();
144 std::string explicit_url = vm["solver-url"].as<std::string>();
145 if (solver_arg == "relap" || solver_arg == "0") {
146 if (!explicit_url.empty()) {
147 std::cerr << "ERROR: --solver-url cannot be used with --solver=relap\n";
148 exit(1);
149 }
150 // solver_url stays empty → RelapSolver
151 } else if (solver_arg == "mock" || solver_arg == "1") {
152 if (!explicit_url.empty()) {
153 g_sim.config.solver_url = explicit_url;
154 } else {
155 g_sim.config.solver_url = "http://localhost:" + std::to_string(solver_port_);
156 }
157 } else if (!explicit_url.empty()) {
158 // Any other --solver value given together with --solver-url: the URL
159 // selects the REST solver. (A bare --solver-url does not reach this
160 // branch, because --solver defaults to "relap" and is rejected above.)
161 g_sim.config.solver_url = explicit_url;
162 } else {
163 std::cerr << "ERROR: unknown solver '" << solver_arg << "'. Use relap|0 or mock|1\n";
164 exit(1);
165 }
166
167 if (vm["no-thermo-cache"].as<bool>()) g_sim.config.thermo_cache_mode = 2;
168 g_sim.config.memory_restart = !vm["no-memory-restart"].as<bool>();
169 g_sim.config.memory_limit_mb = vm["memory-limit"].as<long>();
170 if (!g_sim.config.memory_restart && g_sim.config.memory_limit_mb > 0 && !vm["memory-limit"].defaulted()) {
171 std::cerr << "ERROR: --no-memory-restart and --memory-limit are mutually exclusive\n";
172 exit(1);
173 }
175 // Use /dev/shm on Linux (tmpfs, zero disk I/O), fall back to /tmp elsewhere (macOS)
176 if (fs::exists("/dev/shm"))
177 g_sim.config.shm_prefix = "/dev/shm/adsidac_" + std::to_string(getpid()) + "_";
178 else
179 g_sim.config.shm_prefix = fs::temp_directory_path().string() + "/adsidac_" + std::to_string(getpid()) + "_";
181 std::cout << "Adaptive restart: memory when RSS < " << g_sim.config.memory_limit_mb << "MB, file otherwise" << std::endl;
182 }
183 g_sim.config.compress_queue = vm["compress-queue"].as<bool>();
184 g_sim.config.aggregate_pe_output = vm["aggregate-pe"].as<bool>();
185 g_sim.config.rm_cycle_enabled = vm["enable-rm-cycle"].as<bool>();
186 viz_port_ = vm["viz-port"].as<int>();
187 {
188 std::string vo = vm["viz-outputs"].as<std::string>();
189 if (!vo.empty()) {
190 if (viz_port_ == 0) {
191 std::cerr << "ERROR: --viz-outputs requires --viz-port to be set\n";
192 exit(1);
193 }
194 std::istringstream iss(vo);
195 std::string tok;
196 while (std::getline(iss, tok, ',')) {
197 if (tok == "all") { g_sim.config.viz_output_events = true; g_sim.config.viz_output_end_states = true; }
198 else if (tok == "events") g_sim.config.viz_output_events = true;
199 else if (tok == "es") g_sim.config.viz_output_end_states = true;
200 else { std::cerr << "ERROR: unknown viz output type '" << tok << "'\n"; exit(1); }
201 }
202 std::cout << "Viz outputs:";
203 if (g_sim.config.viz_output_events) std::cout << " events";
204 if (g_sim.config.viz_output_end_states) std::cout << " end-states";
205 std::cout << std::endl;
206 }
207 }
208 if (vm.count("notify-ntfy")) {
209 notify_ntfy_topic = vm["notify-ntfy"].as<std::string>();
210 if (notify_ntfy_topic == "auto")
212 std::cout << "Notifications: ntfy.sh/" << notify_ntfy_topic << std::endl;
213 }
214 if (vm.count("notify-discord"))
215 notify_discord_webhook = vm["notify-discord"].as<std::string>();
216
217 g_sim.config.checkpoint_dir = vm["checkpoint-dir"].as<std::string>();
218 g_sim.config.checkpoint_interval = vm["checkpoint-interval"].as<int>();
219 g_sim.config.checkpoint_stop = vm["checkpoint-stop"].as<bool>();
220 g_sim.config.resume_file = vm["resume"].as<std::string>();
221 // MPI ranks chdir into rank_N/ after option parsing, and the server loads
222 // --resume after that chdir, so a relative path kept here would resolve
223 // against the wrong directory. Both paths are made absolute against the
224 // launch directory now.
225 if (!g_sim.config.checkpoint_dir.empty())
226 g_sim.config.checkpoint_dir = fs::absolute(g_sim.config.checkpoint_dir).string();
227 if (!g_sim.config.resume_file.empty())
228 g_sim.config.resume_file = fs::absolute(g_sim.config.resume_file).string();
230 std::cerr << "ERROR: --checkpoint-interval requires --checkpoint-dir\n";
231 exit(1);
232 }
234 std::cerr << "ERROR: --checkpoint-stop requires --checkpoint-interval\n";
235 exit(1);
236 }
237 if (!g_sim.config.checkpoint_dir.empty()) {
238 fs::create_directories(g_sim.config.checkpoint_dir);
239 std::cout << "Checkpoint: dir=" << g_sim.config.checkpoint_dir
240 << " interval=" << g_sim.config.checkpoint_interval
241 << (g_sim.config.checkpoint_stop ? " (stop after checkpoint)" : "") << std::endl;
242 }
243 if (!g_sim.config.resume_file.empty())
244 std::cout << "Resuming from: " << g_sim.config.resume_file << std::endl;
245 g_sim.config.truncation_time_override = vm["truncation-time"].as<double>();
246 g_sim.config.occupancy_log = vm["occupancy-log"].as<std::string>();
247 {
248 const std::string mm = vm["merge"].as<std::string>();
249 if (mm == "now") g_sim.config.merge_mode = 0;
250 else if (mm == "serial") g_sim.config.merge_mode = 1;
251 else if (mm == "defer") g_sim.config.merge_mode = 2;
252 else {
253 std::cerr << "ERROR: unknown merge mode '" << mm << "'. Use now, serial, or defer\n";
254 exit(1);
255 }
256 g_sim.config.merge_only = vm["merge-only"].as<bool>();
257 g_sim.config.merge_threads = vm["merge-threads"].as<int>();
260 std::cerr << "ERROR: --merge-only does not run a simulation; it cannot be combined "
261 "with --resume or checkpointing\n";
262 exit(1);
263 }
264 // A deferred, unmerged Output/ means the rank dirs are the only complete
265 // copy of the finished run; a resume would wipe them (Setup_Directories).
266 if (!g_sim.config.resume_file.empty()
267 && fs::exists(fs::path(project_directory) / "Output" / "MERGE_PENDING.txt")) {
268 std::cerr << "ERROR: this project has a deferred, unmerged run "
269 "(Output/MERGE_PENDING.txt). Run --merge-only first; resuming now "
270 "would delete the rank directories that hold its outputs\n";
271 exit(1);
272 }
273 }
274
275 // Startup banner printed once from main (serial) or server (MPI)
276
277
278 // Derive the output and input sub-directories from the project directory
279 str1 = "/Output/";
281 output_directory += str1;
282//
283 str1 = "/Output/ES/";
285 es_directory += str1;
286//
287 str1 = "/Output/PE/";
289 pe_directory += str1;
290//
291 str1 = "/Output/KPS/";
293 kps_directory += str1;
294//
295 str1 = "/Input/Crew/Procedures/";
297 eop_directory += str1;
298//
299 str1 = "/Input/Crew/DecisionMaker/";
301 ODM_directory += str1;
302//
303 str1 = "/Input/Crew/ActionTaker/";
305 OAT_directory += str1;
306//
307 str1 = "/Input/Crew/Consultant/";
309 OCT_directory += str1;
310//
311 str1 = "/Input/HardwareReliability/";
314//
315 str1 = "/Input/Indicators/";
317 indicators_directory += str1;
318//
319 str1 = "/Input/Scheduler/";
321 scheduler_directory += str1;
322//
323 str1 = "/Input/System/";
325 system_directory += str1;
326//
327 str1 = "/Input/SupportSystemsReliability/";
330//
332 str1 = scheduler_directory;
333 str1 += "ZCtrlPar.txt";
334 ifstream fin1(str1.c_str(), ios::in);
335 if (!fin1.is_open()) {
336 cout << "File: " << str1 << " cound not be found" << endl;
337 ofstream fout2("err messages.txt", ios::app);
338 fout2 << r5pars_.timesno << " File: " << str1
339 << " cound not be found\n";
340 fout2.close();
341 r5pars_.terminateall = true;
342 return;
343 } else {
344 fin1 >> str1 >> str1 >> sequence_truncation_probabiliy >> str1
346 if (fin1.fail()) {
347 // A failed extraction leaves 0.0 in both values, and a
348 // truncation time of 0 would terminate every sequence at once
349 // while still producing a plausible-looking DET, so a parse
350 // failure is fatal.
351 std::cout << "FATAL: malformed ZCtrlPar.txt — could not parse "
352 << "Truncation_probability / Truncation_time." << std::endl;
353 std::exit(1);
354 }
355 fin1.close();
356 }
357 }
358 // CLI override takes precedence over ZCtrlPar.txt
361}
362
363
365 m_iMode = iMode;
366 r5pars_.tsimmode = static_cast<int>(iMode);
367 string es_directory, str, str1, str2;
368 //initiate fcctrl
369 r5pars_.cnewrst = true;
370 r5pars_.cgennode = false;
371 r5pars_.csnostop = 0;
372 r5pars_.dopltwrt = false;
373// R5PAR_mp_PAR_INIED = false;
374 r5pars_.cnumsno = 0;
375 r5pars_.timesno = -2.0;
376
377 //The following file names need to be modified After GUI is integrated
378 strcpy(r5pars_.carg1, "-i");
379 strcpy(r5pars_.carg3, "-o");
380 strcpy(r5pars_.carg5, "-r");
381 if (iMode == ConsoleMode::Console) {
382 // TODO Use individual folders for separete executions
383 // Console version mode
384// strcpy(r5pars_.carg0, "relap5g");
385 int alp = 1;
386 while (!alp) {
387 sleep(5);
388 }
389 strcpy(r5pars_.carg0, "relap5");
390 strcpy(r5pars_.carg4, "out.o");
391 // RELAP5's internal filename buffers are 80 characters and the carg arrays
392 // are char[100]. A longer path would be truncated by RELAP5 or overflow
393 // the shared struct, so paths above 80 characters are rejected here.
394 constexpr size_t kMaxRelapPath = 80;
396 std::string shm_restart = g_sim.config.shm_prefix + "restart.r";
397 if (shm_restart.size() > kMaxRelapPath) {
398 std::cout << "FATAL: restart path exceeds RELAP5's " << kMaxRelapPath
399 << "-character filename limit: " << shm_restart << std::endl;
400 std::exit(1);
401 }
402 strcpy(r5pars_.carg6, shm_restart.c_str());
403 } else {
404 strcpy(r5pars_.carg6, "restart.r");
405 }
406 if (input_deck_file_directory_and_name.size() > kMaxRelapPath) {
407 std::cout << "FATAL: input deck path is " << input_deck_file_directory_and_name.size()
408 << " characters, exceeding RELAP5's " << kMaxRelapPath
409 << "-character filename limit:\n " << input_deck_file_directory_and_name
410 << "\n Run from a shorter directory or pass a shorter relative path."
411 << std::endl;
412 std::exit(1);
413 }
414 {
415 std::ifstream deck_test(input_deck_file_directory_and_name);
416 if (!deck_test.good()) {
417 std::cout << "FATAL: input deck not found or unreadable: "
419 std::exit(1);
420 }
421 }
422 strcpy(r5pars_.carg2, input_deck_file_directory_and_name.c_str());
423 }
424 //set file name length for FORTRAN use
425 r5pars_.carg0len = (int) strlen(r5pars_.carg0);
426 r5pars_.carg1len = (int) strlen(r5pars_.carg1);
427 r5pars_.carg2len = (int) strlen(r5pars_.carg2);
428 r5pars_.carg3len = (int) strlen(r5pars_.carg3);
429 r5pars_.carg4len = (int) strlen(r5pars_.carg4);
430 r5pars_.carg5len = (int) strlen(r5pars_.carg5);
431 r5pars_.carg6len = (int) strlen(r5pars_.carg6);
432 //
433 // r5pars_.si_unit sets units for ADS-IDAC - True is SI, False is British
434 r5pars_.si_unit = false;
435 //
436 r5pars_.sim_err = false;
437 r5pars_.dopltwrt = false;
438 r5pars_.only_once = false;
439//
440//
442 str = es_directory;
443 str1 = es_directory;
444 str2 = es_directory;
445 str += "Scenario info.txt";
446 str1 += "Procedure data.txt";
447 str2 += "Scan data.txt";
448 remove(str.c_str());
449 remove(str1.c_str());
450 remove(str2.c_str());
451 remove("out.o");
452 remove("restart.r");
453 if (r5pars_.tsimmode == static_cast<int>(ConsoleMode::NetServer) || r5pars_.tsimmode == static_cast<int>(ConsoleMode::Console)) {
454 remove("err messages.txt");
455 }
456 remove("dbg info.txt");
457 remove("Scenario info.txt");
458 remove("Procedure data.txt");
459 // Digest the immutable configuration inputs. Checkpoints store this digest
460 // and a resume refuses on mismatch: snapshots carry execution state only
461 // and a resume reconstructs the configuration from these files, so they
462 // must be the ones the checkpoint was written against. The printed line
463 // also records which configuration produced the run.
466 std::cout << "[CONFIG] fingerprint=0x" << std::hex
467 << g_sim.config_fingerprint << std::dec << std::endl;
468}
470}
472 m_iMode = iMode;
473 string str1;
474 string str;
477 char ch;
479 // console mode or network server mode
480 str1 = "ZiniADS.txt";
481 ifstream fin(str1.c_str(), ios::in);
482 if (!fin.is_open()) {
483 cout << "File ZiniADS.txt cound not be found" << endl;
484 ofstream fout("err messages.txt", ios::app);
485 fout << r5pars_.timesno
486 << " File ZIniADS.txt cound not be found\n";
487 fout.close();
488 r5pars_.terminateall = true;
489 return;
490 } else {
491 do {
492 ch = fin.get();
493 } while (ch != '\n');
494 do {
495 ch = fin.get();
496 if (ch != '\n')
497 project_directory += ch;
498 } while (ch != '\n');
499 // Startup banner printed by caller (main or Server), not here
500 do {
501 ch = fin.get();
502 } while (ch != '\n');
503 do {
504 ch = fin.get();
505 if (ch != '\n')
507 } while (ch != '\n');
508 fin.close();
509 }
510 } else {
511 // Network client mode
512// #ifndef _CONSOLE
513// project_directory = theStrWorkingDir;
514// project_directory += "//ClientRun";
515// input_deck_file_directory_and_name = theStrWorkingDir;
516// input_deck_file_directory_and_name += "//ClientRun//indeck.i";
517// #endif
518 }
519 str1 = "/Output/";
521 output_directory += str1;
522//
523 str1 = "/Output/ES/";
525 es_directory += str1;
526//
527 str1 = "/Output/PE/";
529 pe_directory += str1;
530//
531 str1 = "/Output/KPS/";
533 kps_directory += str1;
534//
535 str1 = "/Input/Crew/Procedures/";
537 eop_directory += str1;
538//
539 str1 = "/Input/Crew/DecisionMaker/";
541 ODM_directory += str1;
542//
543 str1 = "/Input/Crew/ActionTaker/";
545 OAT_directory += str1;
546//
547 str1 = "/Input/Crew/Consultant/";
549 OCT_directory += str1;
550//
551 str1 = "/Input/HardwareReliability/";
554//
555 str1 = "/Input/Indicators/";
557 indicators_directory += str1;
558//
559 str1 = "/Input/Scheduler/";
561 scheduler_directory += str1;
562//
563 str1 = "/Input/System/";
565 system_directory += str1;
566//
567 str1 = "/Input/SupportSystemsReliability/";
570//
572 str1 = scheduler_directory;
573 str1 += "ZCtrlPar.txt";
574 ifstream fin1(str1.c_str(), ios::in);
575 if (!fin1.is_open()) {
576 cout << "File: " << str1 << " cound not be found" << endl;
577 ofstream fout2("err messages.txt", ios::app);
578 fout2 << r5pars_.timesno << " File: " << str1
579 << " cound not be found\n";
580 fout2.close();
581 r5pars_.terminateall = true;
582 return;
583 } else {
584 fin1 >> str1 >> str1 >> sequence_truncation_probabiliy >> str1
586 if (fin1.fail()) {
587 std::cout << "FATAL: malformed ZCtrlPar.txt — could not parse "
588 << "Truncation_probability / Truncation_time." << std::endl;
589 std::exit(1);
590 }
591 fin1.close();
592 }
593 }
594}
596 return project_directory;
597}
599 return output_directory;
600}
602 return es_directory;
603}
605 return pe_directory;
606}
608 return kps_directory;
609}
612}
614 return solver_port_;
615}
617 return eop_directory;
618}
620 return ODM_directory;
621}
623 return OAT_directory;
624}
626 return OCT_directory;
627}
630}
633}
635 return scheduler_directory;
636}
638 return system_directory;
639}
642}
645}
648}
650 project_directory = str;
651}
653 output_directory = str;
654}
656 es_directory = str;
657}
659 pe_directory = str;
660}
662 kps_directory = str;
663}
666}
668 eop_directory = str;
669}
671 ODM_directory = str;
672}
674 OAT_directory = str;
675}
677 OCT_directory = str;
678}
681}
684}
687}
689 system_directory = str;
690}
693}
695 bool terminate_current_sequence = false;
696 int branch_number;
697 BranchEndState *es_pt;
698 string str;
699 vector<BranchEndState *>::reverse_iterator es_ritr;
700 //
701 //
702 if (r5pars_.csnostop != 0) {
703 terminate_current_sequence = true;
704 g_sim.expected_abort = true;
705 }
706 //
709 es_pt = new BranchEndState();
710 str = "Sequence probability reached truncation value: ";
711 es_pt->setConsequenceDescription(str);
714 std::ostringstream streamObj;
716 str += streamObj.str();
717 branch_number = g_sim.Branch_center.getIDOfMotherBranch();
718 //branch_number = Branch_center.getIDOfRecentGeneratedBranch();
719 //
721 g_sim.Aux_info.addRecord(str, branch_number);
722 //
723 terminate_current_sequence = true;
724 g_sim.expected_abort = true;
725 //
726 r5pars_.csnostop = 4;
727 //
728 } else if (r5pars_.timesno > sequence_truncation_time) {
729 es_pt = new BranchEndState();
731 str = "Sequence reached simulation truncation time";
732 es_pt->setConsequenceDescription(str);
734 terminate_current_sequence = true;
735 //
736 branch_number = g_sim.Branch_center.getIDOfMotherBranch();
737 //branch_number = Branch_center.getIDOfRecentGeneratedBranch();
739 g_sim.Aux_info.addRecord(str, branch_number);
740 //
741 g_sim.expected_abort = true;
742 r5pars_.csnostop = 4;
743 } else if (sequence_terminated_by_alarm) {
744 es_pt = new BranchEndState();
748 //
749 branch_number = g_sim.Branch_center.getIDOfMotherBranch();
750 //branch_number = Branch_center.getIDOfRecentGeneratedBranch();
754 //
755 terminate_current_sequence = true;
757 g_sim.expected_abort = true;
758 r5pars_.csnostop = 5;
760 es_pt = new BranchEndState();
765 //
766 branch_number = g_sim.Branch_center.getIDOfMotherBranch();
767 //branch_number = Branch_center.getIDOfRecentGeneratedBranch();
771 branch_number);
772 //
773 terminate_current_sequence = true;
775 g_sim.expected_abort = true;
776 r5pars_.csnostop = 5;
777 } else if (r5pars_.sim_err) {
778 es_pt = new BranchEndState();
782 terminate_current_sequence = true;
783 g_sim.expected_abort = true;
784 r5pars_.csnostop = 6;
785 } else {
786 }
787 return terminate_current_sequence;
788}
791}
794}
797}
800}
803}
806}
807
810}
813}
816}
819}
820
823}
826}
829}
832}
833
834void Scheduler::saveSchedulerToFile(ofstream &fout) {
835 int i_sequence_terminated_by_alarm = 0;
836 int i_sequence_terminated_by_non_response_action = 0;
838 i_sequence_terminated_by_alarm = 1;
840 i_sequence_terminated_by_non_response_action = 1;
841 fout << "Scheduler\n" << project_directory << '\n' << output_directory
842 << '\n' << es_directory << '\n' << pe_directory << '\n'
844 << '\n' << eop_directory << '\n' << ODM_directory << '\n'
845 << OAT_directory << '\n' << OCT_directory << '\n'
847 << '\n' << scheduler_directory << '\n' << system_directory << '\n'
850 << '\n' << OAT_action_time_multiplier << ' '
853 << i_sequence_terminated_by_alarm << ' '
855 << i_sequence_terminated_by_non_response_action << ' '
857 << file_name_restart << '\n' << file_name_ES << '\n' << static_cast<int>(m_iMode)
858 << '\n';
859}
861 int i_sequence_terminated_by_alarm = 0;
862 int i_sequence_terminated_by_non_response_action = 0;
863 string str;
864
865 fin >> str;
866 if (str != "Scheduler") {
867 ofstream fout("err messages.txt", ios::app);
868 cout
869 << "Scheduler::retrieveSchedulerFromFile File retrieval error in previous function"
870 << endl;
871 fout << r5pars_.timesno
872 << " Scheduler::retrieveSchedulerFromFile retrieval error in previous function\n";
873 fout.close();
874 r5pars_.sim_err = true;
876 "Scheduler::retrieveSchedulerFromFile Prior error");
878 return;
879 }
880
891 >> i_sequence_terminated_by_alarm
893 >> i_sequence_terminated_by_non_response_action
896 { int iMode_val; fin >> iMode_val; m_iMode = static_cast<ConsoleMode>(iMode_val); }
897
898 if (i_sequence_terminated_by_alarm == 0) {
900 } else {
902 }
903
904 if (i_sequence_terminated_by_non_response_action == 0) {
906 } else {
908 }
909
910}
943 m_iMode = _ss.getMiMode();
944}
947}
949 file_name_indeck = str;
950}
952 file_name_restart = str;
953}
954void Scheduler::setFileNameES(string str) {
955 file_name_ES = str;
956}
959}
961 return file_name_indeck;
962}
964 return file_name_restart;
965}
967 return file_name_ES;
968}
977 project_directory = "NONE";
978 output_directory = "NONE";
979 es_directory = "NONE";
980 pe_directory = "NONE";
981 kps_directory = "NONE";
983 eop_directory = "NONE";
984 ODM_directory = "NONE";
985 OAT_directory = "NONE";
986 OCT_directory = "NONE";
988 indicators_directory = "NONE";
989 scheduler_directory = "NONE";
990 system_directory = "NONE";
995 file_name_indeck = "NONE";
996 file_name_restart = "NONE";
997 file_name_ES = "NONE";
999}
1001 m_iMode = n;
1002}
1004 return m_iMode;
1005}
1006
1007// #ifndef _CONSOLE
1008
1009// int Scheduler::getClusterNodeSequenceFromSrv() const
1010// {
1011// ::SendMessage(theCltDlg->GetSafeHwnd(),WM_CLUSTERREQUEST,0,0);
1012// ::WaitForSingleObject(g_eventClusterNode,INFINITE);
1013// g_eventClusterNode.ResetEvent();
1014
1015// return theCltDlg->m_iClusterNodeSequence;
1016// }
1017
1018// int Scheduler::getPENodeSequenceFromSrv() const
1019// {
1020// ::SendMessage(theCltDlg->GetSafeHwnd(),WM_PEREQUEST,0,0);
1021// ::WaitForSingleObject(g_eventPENode,INFINITE);
1022// g_eventPENode.ResetEvent();
1023
1024// return theCltDlg->m_iPENodeSequence;
1025// }
1026
1027// int Scheduler::getESNodeSequenceFromSrv() const
1028// {
1029// ::SendMessage(theCltDlg->GetSafeHwnd(),WM_ESREQUEST,0,0);
1030// ::WaitForSingleObject(g_eventESNode,INFINITE);
1031// g_eventESNode.ResetEvent();
1032
1033// return theCltDlg->m_iESNodeSequence;
1034// }
1035
1036// #endif
Command/control dispatch — routes crew decisions to plant actions and branch generation.
std::string notify_discord_webhook
char separator()
Definition: Scheduler.cpp:44
std::string auto_ntfy_topic()
Generate a default ntfy topic name: "ads" + 4 hex chars from hostname hash. Example: "ads7f3a".
std::string notify_ntfy_topic
Global notification targets (set by Scheduler::parseOptions).
Simulation configuration, directory management, CLI options, and truncation control.
ConsoleMode
Definition: SimConstants.h:20
SimulationContext g_sim
Global simulation context: the single instance, defined in SimulationContext.cpp.
document e
void addRecord(std::string, int)
The end state (ES node) that terminates one sequence of the DET.
void setTypeOfConsequence(Consequence)
void setConsequenceDescription(std::string)
std::string getTempESMessage()
void setTempTypeOfConsequence(Consequence)
Stores the consequence of the end state the running sequence will get.
void addAnEndState(BranchEndState *)
Closes the running sequence with an end state and takes ownership of it.
Consequence getTempTypeOfConsequence()
double getRecentUnconditionalBranchProbability()
int getIDOfMotherBranch()
void setTempESMessage(std::string)
Stores the description of the end state the running sequence will get if it is terminated (set by mod...
void displayInformation(std::string strInformation)
std::string getOATDirectory()
Definition: Scheduler.cpp:622
void setFileNameNodeMultiProcessor(std::string)
Definition: Scheduler.cpp:945
ConsoleMode getMiMode()
Definition: Scheduler.cpp:1003
void setODMDirectory(std::string)
Definition: Scheduler.cpp:670
std::string info_sequence_terminated_by_non_response_action
Definition: Scheduler.h:245
bool getSequenceTerminatedByAlarm()
Definition: Scheduler.cpp:811
void setInfoOfSequenceTerminatedByAlarm(std::string)
Definition: Scheduler.cpp:821
std::string file_name_restart
Definition: Scheduler.h:246
void readInfoFromFile(ConsoleMode iMode=ConsoleMode::Console)
Line-based alternative to parseOptions(); the engine's entry points do not call it.
Definition: Scheduler.cpp:471
void setFileNameRestart(std::string)
Definition: Scheduler.cpp:951
void setKPSDirectory(std::string)
Definition: Scheduler.cpp:661
std::string OAT_directory
Definition: Scheduler.h:238
bool checkForTerminatingCurrentSequence()
Decides whether the running sequence ends at this evaluation point.
Definition: Scheduler.cpp:694
std::string pe_directory
Definition: Scheduler.h:236
double sequence_truncation_probabiliy
Definition: Scheduler.h:240
void setESDirectory(std::string)
Definition: Scheduler.cpp:655
std::string getFileNameIndeck()
Definition: Scheduler.cpp:960
double getODMActionTimeMultiplier()
Definition: Scheduler.cpp:792
void setInfoSequenceTerminatedByNonResponseAction(std::string)
Definition: Scheduler.cpp:827
Scheduler()
Constructs a scheduler in the state set by resetScheduler().
Definition: Scheduler.cpp:52
std::string kps_directory
Definition: Scheduler.h:236
std::string getProjectDirectory()
Definition: Scheduler.cpp:595
double getSequenceTruncationTime()
Definition: Scheduler.cpp:646
void setSchedulerDirectory(std::string)
Definition: Scheduler.cpp:685
void setSequenceTerminatedByNonResponseAction(bool)
Definition: Scheduler.cpp:814
void setODMActionTimeMultiplier(double)
Definition: Scheduler.cpp:789
void setHardwareReliabilityDirectory(std::string)
Definition: Scheduler.cpp:679
void setSystemDirectory(std::string)
Definition: Scheduler.cpp:688
std::string getIndicatorsDirectory()
Definition: Scheduler.cpp:631
double getSequenceTruncationProbability()
Definition: Scheduler.cpp:643
void setFileNameIndeck(std::string)
Definition: Scheduler.cpp:948
std::string getESDirectory()
Definition: Scheduler.cpp:601
std::string getFileNameNodeMultiProcessor()
Definition: Scheduler.cpp:957
int solver_port_
Definition: Scheduler.h:247
std::string getSupportSystemsDirectory()
Definition: Scheduler.cpp:640
void setSequenceTerminatedByAlarm(bool)
Definition: Scheduler.cpp:808
std::string info_of_sequence_terminated_by_alarm
Definition: Scheduler.h:244
std::string getHardwareReliabilityDirectory()
Definition: Scheduler.cpp:628
std::string getSchedulerDirectory()
Definition: Scheduler.cpp:634
void saveSchedulerToFile(std::ofstream &)
Writes the scheduler to a text restart stream, starting with the label Scheduler. Strings are written...
Definition: Scheduler.cpp:834
bool getSequenceTerminatedByNonResponseAction()
Definition: Scheduler.cpp:817
std::string input_deck_file_directory_and_name
Definition: Scheduler.h:237
void setEOPDirectory(std::string)
Definition: Scheduler.cpp:667
void copyScheduler(Scheduler &)
Copies directories, truncation settings, multipliers, termination flags, file names and mode from ano...
Definition: Scheduler.cpp:911
std::string getFileNameRestart()
Definition: Scheduler.cpp:963
std::string getInfoSequenceTerminatedByNonResponseAction()
Definition: Scheduler.cpp:830
std::string project_directory
Definition: Scheduler.h:236
std::string OCT_directory
Definition: Scheduler.h:238
double OCT_action_time_multiplier
Definition: Scheduler.h:241
void setOCTDirectory(std::string)
Definition: Scheduler.cpp:676
std::string ODM_directory
Definition: Scheduler.h:238
double sequence_truncation_time
Definition: Scheduler.h:240
void endSimulation()
Does nothing.
Definition: Scheduler.cpp:469
std::string file_name_NodeMultiProcessor
Definition: Scheduler.h:246
void retrieveSchedulerFromFile(std::ifstream &)
Reads the layout written by saveSchedulerToFile. A stream that does not start with the Scheduler labe...
Definition: Scheduler.cpp:860
std::string getOCTDirectory()
Definition: Scheduler.cpp:625
std::string hardware_reliability_directory
Definition: Scheduler.h:239
std::string getFileNameES()
Definition: Scheduler.cpp:966
std::string file_name_ES
Definition: Scheduler.h:246
std::string system_directory
Definition: Scheduler.h:239
void setProjectDirectory(std::string)
Definition: Scheduler.cpp:649
void setIndicatorsDirectory(std::string)
Definition: Scheduler.cpp:682
void setOATActionTimeMultiplier(double)
Definition: Scheduler.cpp:795
bool sequence_terminated_by_non_response_action
Definition: Scheduler.h:243
void setSupportSystemsDirectory(std::string)
Definition: Scheduler.cpp:691
void setPEDirectory(std::string)
Definition: Scheduler.cpp:658
std::string getInfoOfSequenceTerminatedByAlarm()
Definition: Scheduler.cpp:824
void parseOptions(int argc, char *argv[])
Parses the command line and ZiniADS.txt, fills this scheduler and g_sim.config, and reads ZCtrlPar....
Definition: Scheduler.cpp:59
double ODM_action_time_multiplier
Definition: Scheduler.h:241
void setOCTActionTimeMultiplier(double)
Definition: Scheduler.cpp:801
std::string getPEDirectory()
Definition: Scheduler.cpp:604
int getSolverPort() const
Definition: Scheduler.cpp:613
void setFileNameES(std::string)
Definition: Scheduler.cpp:954
void setOATDirectory(std::string)
Definition: Scheduler.cpp:673
bool sequence_terminated_by_alarm
Definition: Scheduler.h:242
void initiationForSimulation(ConsoleMode iMode=ConsoleMode::Console)
Prepares the RELAP5 bridge and the working directory for a run. Call it after parseOptions().
Definition: Scheduler.cpp:364
void setMiMode(ConsoleMode)
Definition: Scheduler.cpp:1000
std::string output_directory
Definition: Scheduler.h:236
double getOATActionTimeMultiplier()
Definition: Scheduler.cpp:798
std::string getSystemDirectory()
Definition: Scheduler.cpp:637
ConsoleMode m_iMode
Definition: Scheduler.h:235
std::string getOutputDirectory()
Definition: Scheduler.cpp:598
std::string support_systems_directory
Definition: Scheduler.h:238
double OAT_action_time_multiplier
Definition: Scheduler.h:241
std::string file_name_indeck
Definition: Scheduler.h:246
void setOutputDirectory(std::string)
Definition: Scheduler.cpp:652
std::string getInputDeckFileDirectoryAndName()
Definition: Scheduler.cpp:610
std::string scheduler_directory
Definition: Scheduler.h:239
std::string getEOPDirectory()
Definition: Scheduler.cpp:616
std::string getODMDirectory()
Definition: Scheduler.cpp:619
std::string getKPSDirectory()
Definition: Scheduler.cpp:607
void resetScheduler()
Resets every member to its default: multipliers 1.0, termination flags off, all directories,...
Definition: Scheduler.cpp:969
void setInputDeckFileDirectoryAndName(std::string)
Definition: Scheduler.cpp:664
std::string indicators_directory
Definition: Scheduler.h:239
double getOCTActionTimeMultiplier()
Definition: Scheduler.cpp:804
std::string es_directory
Definition: Scheduler.h:236
std::string eop_directory
Definition: Scheduler.h:238
virtual ~Scheduler()
Definition: Scheduler.cpp:56
int viz_port_
Definition: Scheduler.h:248
struct @0 r5pars_
uint64_t compute_config_fingerprint(const std::string &project_dir, const std::string &deck_path)
Digest the configuration inputs of a project.
std::string resume_file
–resume checkpoint file as an absolute path (empty = fresh start)
Definition: SimConfig.h:31
bool rm_cycle_enabled
–enable-rm-cycle: ReasonMachine snapshot/restore/serialize/tbi machinery (see docs/developer/internal...
Definition: SimConfig.h:46
std::string checkpoint_dir
–checkpoint-dir as an absolute path, created at startup (empty = disabled)
Definition: SimConfig.h:28
bool checkpoint_stop
–checkpoint-stop: exit after the first checkpoint written; requires checkpoint_interval > 0
Definition: SimConfig.h:30
int checkpoint_interval
–checkpoint-interval: checkpoint every N completed sequences (0 = disabled); requires checkpoint_dir
Definition: SimConfig.h:29
std::string shm_prefix
Path prefix for memory-restart files: "/dev/shm/adsidac_<pid>_" when /dev/shm exists,...
Definition: SimConfig.h:26
long memory_limit_mb
–memory-limit [MB]: 0 = unlimited; >0 = keep a restart buffer in memory only while process RSS is bel...
Definition: SimConfig.h:21
int merge_mode
Definition: SimConfig.h:38
bool merge_only
Definition: SimConfig.h:42
double truncation_time_override
CLI –truncation-time override [s] (0 = use ZCtrlPar.txt value). Not stored in checkpoints.
Definition: SimConfig.h:36
int thermo_cache_mode
0 = reuse cached steam tables (default), 2 = force reload every sequence (–no-thermo-cache)....
Definition: SimConfig.h:19
int merge_threads
–merge-threads for –merge-only, threads over rank dirs (0 or less = min(8, hardware threads))
Definition: SimConfig.h:45
bool compress_queue
–compress-queue (default off): LZ4-compress RELAP restart buffers held and sent between MPI ranks
Definition: SimConfig.h:22
bool viz_output_end_states
Stream end states to viz server (–viz-outputs=es or all)
Definition: SimConfig.h:35
bool viz_output_events
Stream PE events to viz server (–viz-outputs=events or all)
Definition: SimConfig.h:34
std::string solver_url
REST solver URL (empty = use RELAP5). –solver=mock gives "http://localhost:<--solver-port,...
Definition: SimConfig.h:27
bool memory_restart
In-memory restart. parseOptions() sets it to !–no-memory-restart, so it is TRUE in every run unless –...
Definition: SimConfig.h:20
bool aggregate_pe_output
Definition: SimConfig.h:23
std::string occupancy_log
–occupancy-log path: CSV of server queue/worker occupancy (empty = disabled, MPI only)....
Definition: SimConfig.h:37
uint64_t config_fingerprint
FNV-1a of immutable config inputs (see ConfigFingerprint.h); 0 = not computed.
CommandControlCenter Command_handler
Command/control dispatch.
AnalysisInfoContainer Aux_info
Analysis records.
BranchRecord Branch_center
Dynamic event tree state.
bool expected_abort
Sequence ended abnormally.