2#include "../Scheduler/Scheduler.h"
3#include "../Notification/Notification.h"
4#include "../Global/SimulationContext.h"
5#include "../Global/OutputMerge.h"
9namespace fs = std::filesystem;
11parallelexec::parallelexec() {
23void parallelexec::parallel_init (
int *argc,
char **argv[])
25 double wtime = MPI_Wtime();
26 MPI_Comm_rank (MPI_COMM_WORLD, &
PG::rank);
27 MPI_Comm_size (MPI_COMM_WORLD, &
PG::size);
32 std::cout <<
"MPI execution (" <<
PG::size <<
" ranks: 1 server + "
33 <<
PG::size - 1 <<
" workers)" << std::endl;
49 server.getSequencesCompleted(),
51 PU::print_message(
PG::rank,
"Merge deferred: rank outputs kept. Consolidate with: "
56 PU::print_message(
PG::rank,
"[MERGE] --merge=defer ignored: a checkpoint-stop "
57 "needs its intermediate merge for resume",
PG::log);
58 server.merge_outputs();
64 summary.
sequences = server.getSequencesCompleted();
73 ParallelUtilities::print_message(
PG::rank,
"Client Parallel Execution",
PG::log);
85 MPI_Barrier(MPI_COMM_WORLD);
88 PU::print_message(
PG::rank,
"Total simulation time: " + std::to_string(MPI_Wtime()-wtime),
PG::log);
92void parallelexec::Setup_Directories() {
101 const fs::path launch_cwd = fs::current_path(ec);
103 const fs::path rankDir = base / (
"rank_" + std::to_string(
PG::rank));
108 fs::remove_all(rankDir, ec);
109 fs::create_directories(rankDir, ec);
111 std::cerr <<
"rank " <<
PG::rank <<
": cannot create " << rankDir
112 <<
" (" << ec.message() <<
")" << std::endl;
119 for (
const auto& name : {
"tpfh2o",
"tpfh2onew",
"tpfd2o"}) {
120 for (
const fs::path& dir : {launch_cwd, base}) {
121 const fs::path src = dir / name;
122 if (fs::exists(src, ec)) {
123 fs::copy(src, rankDir / name, fs::copy_options::overwrite_existing, ec);
125 std::cerr <<
"rank " <<
PG::rank <<
": cannot copy " << name
126 <<
" (" << ec.message() <<
")" << std::endl;
133 const std::string dirName = rankDir.string();
135 if (!SetCurrentDirectory(dirName.c_str())) {
136 std::cerr <<
"Failed to change directory on Windows" << std::endl;
140 if (chdir(dirName.c_str()) != 0) {
141 perror(
"Failed to change directory on Unix/Linux");
147 freopen(
"rank_output.log",
"w", stdout);
148 freopen(
"rank_errors.log",
"w", stderr);
149 setvbuf(stdout,
nullptr, _IOLBF, 0);
150 setvbuf(stderr,
nullptr, _IOLBF, 0);
void send_completion_notification(const RunSummary &summary)
Send completion notifications to all configured targets. Non-fatal: prints a warning if curl fails,...
void set_global_client(Client *c)
MPI parallel execution manager — initialization, Server/Client dispatch, serialization.
SimulationContext g_sim
Global simulation context: the single instance, defined in SimulationContext.cpp.
MPI worker client that executes simulation sequences.
std::string getProjectDirectory()
double getSequenceTruncationTime()
void parseOptions(int argc, char *argv[])
Parses the command line and ZiniADS.txt, fills this scheduler and g_sim.config, and reads ZCtrlPar....
std::string getInputDeckFileDirectoryAndName()
MPI server that manages the DET task queue and client dispatch.
bool log
Enable/disable rank-specific logging.
int size
Total number of MPI processes.
int rank
MPI rank of this process.
void write_manifest(const std::string &project_dir, int ranks, bool aggregate, long sequences, unsigned long long fingerprint)
Write the –merge=defer manifest <project_dir>/Output/MERGE_PENDING.txt (Output/ is created if needed;...
Summary of a completed simulation run.
std::string solver_url
REST solver URL (empty = use RELAP5). –solver=mock gives "http://localhost:<--solver-port,...
Scheduler SScheduler
Simulation scheduling, parses CLI options.
uint64_t config_fingerprint
FNV-1a of immutable config inputs (see ConfigFingerprint.h); 0 = not computed.