6#include "../Global/RestartTrim.h"
9#include "../Global/fmodule.h"
10#include "../ParallelExec/ParallelGlobal.h"
12#include "../ParallelExec/ParallelExecution.h"
20#include "../Global/SimulationContext.h"
21#include "../Global/SharedConfig.h"
22#include "../Global/CheckedIO.h"
37 bool terminate_current_sequence =
false;
42 str =
"Plant model simulation failure";
50 str =
"Sequence terminated by RELAP5";
87 terminate_current_sequence =
89 if (!terminate_current_sequence) {
92 str = std::to_string(
r5pars_.cnbranch);
93 str +=
" branches are generated";
95 cout <<
" " <<
r5pars_.timesno <<
" " << str << endl;
96 std::shared_ptr<RestartNodeInfo> restart_info_pt_1 = make_shared<RestartNodeInfo>();
101 restart_info_pt_1->saveRestartNodeInfo();
102 int enq_cid = restart_info_pt_1->getCorrespondingBranchClusterID();
163 int cid = rinfo->getCorrespondingBranchClusterID();
165 std::string branch_name =
"restart_" + std::to_string(local_id)
166 +
"_cid" + std::to_string(cid) +
".r";
168 std::string local_branch_path = use_mem
170 : (
"../rank_" + std::to_string(
PG::rank) +
"/" + branch_name);
196 static const bool trim_enabled = [] {
197 const char* v = std::getenv(
"ADS_RESTART_TRIM");
198 return v && *v ==
'1';
200 if (bc && !ckpt_buf.empty() && trim_enabled) {
209 static bool base_published =
false;
210 if (!base_published) {
211 const std::string base_path =
214 if (!std::filesystem::exists(base_path, ec)) {
218 const std::string tmp = base_path +
".r"
219 + std::to_string(
PG::rank) +
".tmp";
221 std::filesystem::rename(tmp, base_path, ec);
222 if (ec) std::filesystem::remove(tmp, ec);
225 base_published =
true;
230 if (
const char* t = std::getenv(
"ADS_MEMBUF_TRACE"); t && *t ==
'1') {
231 std::cout <<
"[TRIM] cid=" << cid <<
" ncount=" << want
232 <<
" " << ckpt_buf.size() / 1048576.0 <<
" MB -> "
233 << one.size() / 1048576.0 <<
" MB ("
234 << (double)ckpt_buf.size() / one.size() <<
"x)" << std::endl;
236 ckpt_buf = std::move(one);
238 PU::print_message(
PG::rank,
"[TRIM] cid=" + std::to_string(cid)
239 +
" ncount=" + std::to_string(want)
240 +
" not found in buffer — sending it whole",
PG::log);
247 rinfo->relap_restart_buf =
lz4_compress(ckpt_buf.data(),
static_cast<int>(ckpt_buf.size()));
249 rinfo->relap_restart_buf = std::move(ckpt_buf);
253 if (!ckpt_buf.empty()) {
255 auto comp =
lz4_compress(ckpt_buf.data(),
static_cast<int>(ckpt_buf.size()));
263 int num_branches =
static_cast<int>(bc->
all_branch.size());
265 PU::print_message(
PG::rank,
"[PEER] CID=" + std::to_string(cid)
266 +
" branches=" + std::to_string(num_branches)
267 +
" RSS=" + std::to_string(
get_rss_mb()) +
"MB"
268 +
" buf=" + std::to_string(rinfo->relap_restart_buf.size()/1024/1024) +
"MB",
PG::log);
275 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
280 std::string rinfo_bytes, branch_bytes;
281 if (num_direct > 0) {
282 rinfo_bytes = PU::serialize_object(*rinfo);
286 for (
int i = 0; i < num_direct; i++) {
287 int target_rank, branch_index, seq_id, parent_seq_id;
289 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
291 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
293 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
295 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
297 PU::print_message(
PG::rank,
"[PEER] Direct send -> C["
298 + std::to_string(target_rank) +
"] bi="
299 + std::to_string(branch_index) +
" seq=" + std::to_string(seq_id),
PG::log);
303 int path_len =
static_cast<int>(local_branch_path.size());
305 MPI_Send(local_branch_path.c_str(), path_len, MPI_CHAR,
314 MPI_COMM_WORLD, MPI_STATUS_IGNORE);
316 if (num_queued > 0) {
323 rinfo->relap_restart_buf.clear();
324 rinfo->relap_restart_buf.shrink_to_fit();
329 PU::print_message(
PG::rank,
"[PEER] Branch done: "
330 + std::to_string(num_direct) +
" direct, "
331 + std::to_string(num_queued) +
" queued (held locally)",
PG::log);
340 bool found_restart_point =
false;
342 string content =
"100 restart transnt\n101 run\n103 ";
344 size_t chosen_idx =
static_cast<size_t>(-1);
346 for (
size_t idx = 0; idx < total; ++idx) {
354 if (chosen_idx !=
static_cast<size_t>(-1)) {
362 solver.
restore(buf_it->second);
364 std::string backup =
restart_path(
"restart_seq_" + std::to_string(seq_it->second) +
".r");
365 std::ifstream ifs(backup, std::ios::binary | std::ios::ate);
366 if (!ifs || ifs.tellg() <= 0) {
367 std::cerr <<
"ERROR: cannot read restart file: " << backup << std::endl;
369 auto file_sz =
static_cast<size_t>(ifs.tellg());
371 std::vector<char> buf(file_sz);
372 ifs.read(buf.data(),
static_cast<std::streamsize
>(file_sz));
378 found_restart_point =
true;
383 bc->savePENodeToFile();
388 std::string bkp =
restart_path(
"restart_seq_" + std::to_string(s) +
".r");
389 if (fs::exists(bkp)) fs::remove(bkp);
393 cout <<
"All sequences have been simulated" << endl;
396 if (found_restart_point) {
397 content += to_string(n_count);
399 ofstream fout(
"indeck.i", ios::out);
403 ofstream fout(
"err messages.txt", ios::app);
404 cout <<
"restartForANewSequence: could not find the restart point."
407 <<
" restartForANewSequence: could not find the restart point.\n";
416 bool found_restart_branch =
false;
417 bool found_restart_info =
false;
418 int restart_branch_cluster_ID = -1, restart_branch_num = -1, new_branch_ID;
419 int id_of_mother_branch_cluster, id_of_mother_branch;
423 std::shared_ptr<RestartNodeInfo> restart_info_pt;
432 if (curr < (
static_cast<int>(bc->
all_branch.size()) - 1)) {
433 found_restart_branch =
true;
434 restart_branch_cluster_ID = cid;
435 restart_branch_num = curr + 1;
441 restart_branch_pt = bc->
all_branch.at(restart_branch_num).get();
452 mother_branch = mother_bc_pt->
findBranch(id_of_mother_branch);
454 mother_branch->
child_IDs.push_back(new_branch_ID);
461 if (found_restart_branch) {
462 bool cid_consumed =
false;
464 if (*ri && (*ri)->getCorrespondingBranchClusterID() == restart_branch_cluster_ID) {
465 found_restart_info =
true;
466 restart_info_pt = *ri;
469 cid_consumed = (bc && restart_branch_num >=
static_cast<int>(bc->
all_branch.size()) - 1);
479 if (found_restart_info) {
506 restart_info_pt->r_All_procedure);
508 restart_info_pt->r_Aux_info);
511 restart_info_pt->r_Command_handler);
513 restart_info_pt->r_Decision_Maker);
515 restart_info_pt->r_Action_Taker);
518 restart_info_pt->r_System_reliability);
520 restart_info_pt->r_All_polynomial);
529 static const bool inject_on_restart = [] {
530 const char* v = std::getenv(
"ADS_RESTART_INJECT");
531 return !(v && *v ==
'0');
533 if (inject_on_restart) {
540 int consumed_seq = cs_it->second;
542 bool still_needed =
false;
544 if (s == consumed_seq) { still_needed =
true;
break; }
547 std::string bkp =
restart_path(
"restart_seq_" + std::to_string(consumed_seq) +
".r");
548 if (fs::exists(bkp)) {
556 ofstream fout(
"err messages.txt", ios::app);
558 <<
"\tADSV2::initiationForRestart: found restart branch but not restart info node."
561 <<
"\tADSV2::initiationForRestart: found restart branch but not restart info node.\n";
565 ofstream fout(
"err messages.txt", ios::app);
567 <<
"\tADSV2::initiationForRestart: count not find restart branch."
570 <<
"\tADSV2::initiationForRestart: count not find restart branch.\n";
void outputErrMessageToFile(string)
void ads_membuf_get_(char **ptr, int *sz)
Engine-side implementation of SolverCallback.
void write_file_or_die(const std::string &path, const char *data, size_t size)
Write an entire buffer to a binary file (truncating it); fatal on any failure.
std::vector< char > lz4_compress(const char *data, int size)
LZ4-compress a buffer with a 4-byte original-size header.
bool should_use_memory_restart()
Decide whether to use memory mode for this restart operation. memory_limit_mb == 0 → unlimited (alway...
std::string restart_path(const std::string &name)
Get restart file path (shm or local).
long get_rss_mb()
Get current process RSS in MB (Linux + macOS, returns 0 elsewhere).
SimulationContext g_sim
Global simulation context: the single instance, defined in SimulationContext.cpp.
void onBranchingPoint(ThermalHydraulicSolver &solver) override
Hand the branches of the newest branch point to the MPI scheduler.
void onScenarioStart(ThermalHydraulicSolver &solver) override
Update plant parameter values, initialize the control panel and refresh the support-system display st...
void onFirstInit(ThermalHydraulicSolver &solver) override
Read the input files of every engine module and initialize them.
void initiationForRestart(ThermalHydraulicSolver &solver)
Restore the C++ simulation state for the branch about to run.
void onTimestepAction(ThermalHydraulicSolver &solver) override
No-op: the engine has no timestep-level actions.
void onEvaluationPoint(ThermalHydraulicSolver &solver) override
One engine cycle at an evaluation point.
void restartForNewSequence(ThermalHydraulicSolver &solver)
Serial path: find the next unexplored branch and prepare its restart.
void clearAnalysisInfoContainerForRestart()
void addRecord(std::string, int)
void copyAnalysisInfoContainerForRestart(AnalysisInfoContainer &)
int getNCountForRestartRELAP5()
int getIDOfMotherCluster()
BranchProbability * findBranch(int)
Finds the alternative with the given branch ID, searching from the last alternative.
int getIDOfThisBranchCluster()
int getCurrentBranchNum()
void setCurrentBranchNum(int)
Sets the index (within all_branch) of the most recently started alternative. Alternatives with a larg...
int getIDOfTheMotherBranch()
std::vector< std::unique_ptr< BranchProbability > > all_branch
The alternatives of this branching point; index 0 is the one the generating sequence continues on.
The end state (ES node) that terminates one sequence of the DET.
void setTypeOfConsequence(Consequence)
void setConsequenceDescription(std::string)
One alternative of a BranchCluster, i.e. one PE node of the DET.
void setIDOfThisBranch(int)
double getUnconditionalBranchProbability()
std::vector< int > child_IDs
void sendBranchInfoToCommandCenter(int)
Hands the content of this alternative to the command center (g_sim.Command_handler)....
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.
void clearBranchRecordForRestart()
Clears the pending forks only (same as clearBranches()).
void clearBranches()
Drops every pending fork and system alarm and resets the pending branch types and counts....
int getIDOfRecentGeneratedES()
int checkAndAddBranchCluster()
Expands the pending forks into a new BranchCluster.
int getIDOfRecentGeneratedBranchCluster()
void setIDOfMotherBranch(int)
void setIDOfRecentGeneratedBranch(int)
int getIDOfRecentGeneratedBranch()
void setRecentUnconditionalBranchProbability(double)
BranchCluster * findBrnachCluster(int)
Finds a cluster by ID, searching from the most recent cluster.
std::vector< std::unique_ptr< BranchCluster > > branch_cluster
All branching points generated so far, in creation order.
void sendCurrentBranchCommandToCommandCenter()
Sends the content of the running sequence's alternative of the most recent cluster to the command cen...
void setTempESMessage(std::string)
Stores the description of the end state the running sequence will get if it is terminated (set by mod...
void setIDOfMotherCluster(int)
void copyCalculationAidFromRestartInfoForRestart(const CalculationAid &)
void clearCalculationAidForRestart()
void hold_branch_data(int cid, std::shared_ptr< RestartNodeInfo > rinfo, BranchRecord &br, const std::string &path, int refs)
Store branch data for deferred peer transfer or a later self-run.
int branches_this_seq_
Count of branching events during current sequence.
int getNextLocalBranchID()
Increment and return the rank-local branch-point counter. The value names restart transfer files and ...
void sendInfoToCommunicationPlace()
void copyCommandControlCenterFromRestartInfo(CommandControlCenter &)
void clearCommandControlCenteForRestart()
void clearCommunicationPlaceAllPointers()
void clearCommunicationPlaceForRestart()
void copyControlPanelForRestart(ControlPanel &)
void initiationForSimulation()
void checkAndActiveComponentFailure()
Registers the hardware forks that are due at the current evaluation point.
void copyHWReliabilityModule(HWReliabilityModule &)
Appends deep copies of the units of another module and copies its state of activation....
void clearForRestart()
Removes all units and resets the state of activation.
void readInfoFromFile()
Loads SystemReliability.txt from the hardware reliability directory (Scheduler::getHardwareReliabilit...
void checkAndExecuteInitiatingEvent()
void InitiationForSimulation()
void copyInitiatingEventController(InitiatingEventController &)
void clearInitiatingEventController()
void clearKeyParameterHistory()
void copyKeyParameterHistory(KeyParameterHistory &)
void oneThroughProcessForBlockI()
void clearOperatorATForRestart()
void oneThroughProcessForBlockD()
void copyOperatorATFromRestartInfo(OperatorAT &)
void copyOperatorDMFromRestartInfo(OperatorDM &)
void oneThroughProcessForBlockD()
void clearOperatorDMForRestart()
void oneThroughProcessForBlockI()
void updateEvidenceForAllPSFs()
std::unique_ptr< ReasonMachine > m_RM
void checkCompletenessOfSystemDecomposition(int)
EventSymptomMatrix diagnosis_matrix
bool getPauseMentalProcedure()
void initiationForSimulation()
void copyProceduresFromRestartInfoForRestart(Procedures &)
void initiationForSimulation()
void clearProceduresForRestart()
bool checkForTerminatingCurrentSequence()
Decides whether the running sequence ends at this evaluation point.
std::string getProjectDirectory()
void updateSupportSystemDisplayStates()
void checkAndActiveSupportSystemFailure()
void executeActionsToInteractWithSystem()
void updateParametersValues()
int setConnectionToRELAP5()
Abstract interface for thermal-hydraulic solvers.
virtual bool isTerminateAll() const =0
True if all simulation should terminate.
virtual void restore(const std::vector< char > &data)=0
Restore the solver's state from a buffer returned by checkpoint().
virtual void setTerminateAll(bool v)=0
Set the terminate-all flag.
virtual std::vector< char > checkpoint()=0
Extract the solver's restart checkpoint as an opaque byte buffer.
bool log
Enable/disable rank-specific logging.
@ server_branch_meta
Client A -> Server: branch metadata only (rank-local branch id + num_branches)
@ client_peer_assign
Server -> Client A: peer assignment list for direct sends.
@ client_peer_restart
Client A -> Client B: direct peer-to-peer restart data.
int rank
MPI rank of this process.
void set_shared_procedures(const Procedures *master)
void set_shared_kb(int operator_type, const KB *master)
void set_shared_control_panel(const ControlPanel *master)
void set_shared_diagnosis_matrix(int operator_type, const EventSymptomMatrix *master)
std::vector< char > extract_record_no_base(const std::vector< char > &buf, std::int32_t want)
[header][target], the wire payload with the base omitted.
std::vector< char > extract_header_and_base(const std::vector< char > &buf)
[header][complete base], the run-wide constant that is cached per rank and published as <project>/res...
std::string shm_prefix
Path prefix for memory-restart files: "/dev/shm/adsidac_<pid>_" when /dev/shm exists,...
int is_mpi_environment
1 if OMPI_COMM_WORLD_SIZE or PMI_SIZE is set in the environment, 0 for serial
bool compress_queue
–compress-queue (default off): LZ4-compress RELAP restart buffers held and sent between MPI ranks
int seq_restart_branch_num
Branch index within that cluster.
SupportSystemReliabilityModule Support_system_reliability
Support system reliability.
Scheduler SScheduler
Simulation scheduling, parses CLI options.
Procedures All_procedure
Emergency operating procedures.
OperatorAT Action_Taker
Crew action execution model.
KeyParameterHistory KPS
Time-series parameter recording.
int seq_restart_cid
CID of restart-origin cluster.
std::vector< std::pair< double, int > > current_seq_events
(branching_time, num_branches) pairs
ControlPanel Indicator
Control room panel state.
HWReliabilityModule System_reliability
Hardware fault trees.
OperatorDM Decision_Maker
Crew decision-making model.
SystemModule Plant
Maps RELAP5 card numbers to C++ objects.
std::map< int, std::vector< char > > restart_buffers
seq_id -> RELAP5 restart buffer
CommandControlCenter Command_handler
Command/control dispatch.
InitiatingEventController IE
Initiating event definition.
int id_epoch_base
Branch-ID epoch for resumed MPI runs; 0 = fresh run.
bool fresh_restart
One-shot flag for restart init.
bool branches_generated_this_sequence
True if branches generated this seq.
std::map< int, int > cid_to_source_sequence
Maps cluster ID to source sequence.
CommunicationPlace Communication_place
Inter-module communication.
AnalysisInfoContainer Aux_info
Analysis records.
BranchRecord Branch_center
Dynamic event tree state.
std::deque< std::shared_ptr< RestartNodeInfo > > restart_info
Restart checkpoints for FIFO.
bool expected_abort
Sequence ended abnormally.
CalculationAid All_polynomial
Polynomial calculations.