Commit 2e273310 authored by Lukas Weber's avatar Lukas Weber
Browse files

readding the single runner functionality

you can now always run your code using the single core scheduler without
rebuild. this breaks compatibility with existing mc implementations
because the incantation to start load_leveller was simplified a little.
parent e9600998
......@@ -26,7 +26,7 @@ set(SRCs
runner.cpp
merge.cpp
mc.cpp
#runner_single.cpp
runner_single.cpp
runner_pt.cpp
)
......
......@@ -329,6 +329,18 @@ inline void MTRand::reload()
left = N, pNext = state;
}
// MPI_Comm_rank will fail if this is not run in an mpi context, but in that
// case the rank distinction is not actually needed.
static uint32_t get_rank() {
int initialized;
MPI_Initialized(&initialized);
if(initialized) {
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
return rank;
}
return 0;
}
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
{
......@@ -338,11 +350,7 @@ inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
static uint32 differ = 0; // guarantee time-based seeds will change
#ifndef MCL_SINGLE
int myrank;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
differ=(uint32)(myrank);
#endif
differ = get_rank();
uint32 h1 = 0;
unsigned char *p = (unsigned char *) &t;
......
#pragma once
#include "merge.h"
#include "runner.h"
#include "runner_single.h"
namespace load_leveller {
template <class mc_runner>
static int run_mc(std::function<abstract_mc * (string&)> mccreator, int argc, char **argv) {
if(argc < 4) {
cerr << "Usage: " << argv[0] <<" jobfile walltime checkpointtime [h/m/s]\nThe last argument sets the time unit for walltime and checkpointtime. Default is seconds."<< endl;
return -1;
}
string jobfile = argv[1];
double walltime = atof(argv[2]);
double chktime = atof(argv[3]);
if(argc>4) {//default is seconds
if(argv[4][0] == 'h') {
walltime *= 3600;
chktime *= 3600;
}
if(argv[4][0] == 'm') {
walltime *= 60;
chktime *= 60;
}
}
mc_runner r;
return r.start(jobfile, walltime, chktime, mccreator, argc, argv);
}
// run this function from main() in your code.
template <class mc_implementation>
int run(int argc, char **argv) {
auto mccreator = [&] (string taskfile) -> abstract_mc* {return new ising(taskfile);};
if(argc > 1 && string(argv[1]) == "merge") {
return merge(mccreator, argc-1, argv+1);
} else if(argc > 1 && string(argv[1]) == "single") {
return run_mc<runner_single>(mccreator, argc-1, argv+1);
}
return run_mc<runner>(mccreator, argc, argv);
}
}
#pragma once
// used by the runner
struct one_task
{
int task_id;
int is_done;
int n_steps;
int steps_done;
int mes_done;
int run_counter;
};
......@@ -11,37 +11,18 @@ runner :: ~runner()
delete sys;
}
int runner :: start(int argc, char *argv[], function<abstract_mc* (string &)> mccreator)
int runner :: start(const std::string& jobfile, double walltime, double checkpointtime, function<abstract_mc* (string &)> mccreator, int argc, char **argv)
{
this->jobfile = jobfile;
this->walltime = walltime;
chktime = checkpointtime;
my_mccreator = mccreator;
if(argc > 1 && string(argv[1]) == "merge") {
return merge(mccreator, argc-1, argv+1);
}
if(argc < 2) {
cerr << "Usage: " << argv[0] <<" jobfile [walltime] [checkpointtime] "<< endl;
return -1;
}
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
my_mccreator=mccreator;
jobfile = argv[1];
parser parsedfile(jobfile);
if (argc>2) walltime=atof(argv[2]);
else walltime = parsedfile.return_value_of<double>("walltime");
if (argc>3) chktime=atof(argv[3]);
else chktime = parsedfile.return_value_of<double>("checkpointtime");
if (argc>4) {//default is seconds
if (argv[4][0]=='h') {
walltime*=3600;
chktime*=3600;
}
if (argv[4][0]=='m') {
walltime*=60;
chktime*=60;
}
}
taskfiles= parsedfile.return_vector< string >("@taskfiles");
time_start = MPI_Wtime();
......
......@@ -16,18 +16,7 @@
#include "measurements.h"
#include "dump.h"
#include "parser.h"
//! One_task
/*! Carries the information for one task and is transferred by mpi */
struct one_task
{
int task_id;
int is_done;
int n_steps;
int steps_done;
int mes_done;
int run_counter;
};
#include "one_task.h"
//! Runner
/*! The main interface for inter-process communications and job management. The master and slave members are included here. */
......@@ -92,7 +81,7 @@ class runner
runner();
~runner();
int start(int argc, char *argv[], function<abstract_mc* (string &)> mccreator);
int start(const string& jobfile, double walltime, double checkpointtime, function<abstract_mc* (string &)> mccreator, int argc, char **argv);
};
......
#include "runner_single.h"
#include "merge.h"
runner_single::runner_single(int argc, char *argv[]) {
jobfile = argv[1];
runner_single::runner_single() {
}
runner_single::~runner_single() {
(*STATUS).close();
delete STATUS;
delete sys;
}
int runner_single :: start(const std::string& jobfile, double walltime, double checkpointtime, function<abstract_mc* (string &)> mccreator, int argc, char **argv)
{
this->jobfile = jobfile;
this->walltime = walltime;
chktime = checkpointtime;
parser parsedfile(jobfile);
if (argc > 2)
walltime = atof(argv[2]);
else
walltime = parsedfile.return_value_of<double>("walltime");
if (argc > 3)
chktime = atof(argv[3]);
else
chktime = parsedfile.return_value_of<double>("checkpointtime");
taskfiles = parsedfile.return_vector<string>("@taskfiles");
time_start = time(NULL);
time_last_chkpt = time_start;
statusfile = parsedfile.value_or_default<string>("statusfile", jobfile + ".status");
masterfile = parsedfile.value_or_default<string>("masterfile", jobfile + ".master");
STATUS = new std::ofstream(statusfile.c_str(), std::ios::out | std::ios::app);
}
runner_single::~runner_single() {
(*STATUS).close();
delete STATUS;
delete sys;
}
void runner_single::start() {
read();
int task_id = get_new_task_id();
while (task_id != -1) {
......@@ -37,25 +38,25 @@ void runner_single::start() {
stringstream rb;
rb << taskdir << "/run" << 1 << ".";
rundir = rb.str();
sys = new mc(taskfile);
if ((*sys).measure.read(rundir) && (*sys).read(rundir)) {
sys = mccreator(taskfile);
if (sys->measure.read(rundir) && sys->_read(rundir)) {
(*STATUS) << 0 << " : L " << rundir << "\n";
cerr << 0 << " : L " << rundir << "\n";
} else {
(*STATUS) << 0 << " : I " << rundir << "\n";
cerr << 0 << " : I " << rundir << "\n";
(*sys).init();
sys->_init();
checkpointing();
}
#ifdef NO_TASK_SHARE
while ((*sys).work_done()<0.5) {
while (sys->work_done()<0.5) {
#else
while (tasks[task_id].mes_done < tasks[task_id].n_steps) {
#endif
(*sys).do_update();
sys->_do_update();
++tasks[task_id].steps_done;
if ((*sys).is_thermalized()) {
(*sys).do_measurement();
if (sys->is_thermalized()) {
sys->do_measurement();
++tasks[task_id].mes_done;
}
if (is_chkpt_time()) {
......@@ -76,6 +77,8 @@ void runner_single::start() {
}
write();
end_of_run();
return 0;
}
bool runner_single::is_chkpt_time() {
......@@ -167,8 +170,8 @@ void runner_single::report() {
void runner_single::checkpointing() {
cerr << "0 : C " << rundir << "\n";
(*sys).write(rundir);
(*sys).measure.write(rundir);
sys->_write(rundir);
sys->measure.write(rundir);
(*STATUS) << "0 : C " << rundir << "\n";
cerr << "0 : C " << rundir << " done" << "\n";
}
......@@ -176,7 +179,7 @@ void runner_single::checkpointing() {
void runner_single::merge_measurements() {
cerr << "0 : M " << rundir << "\n";
std::string mf = taskdir + ".out";
(*sys).write_output(mf);
sys->_write_output(mf);
(*STATUS) << 0 << " : M " << taskdir << "\n";
cerr << "0 : M " << rundir << " done" << "\n";
}
......
......@@ -18,15 +18,7 @@
#include "measurements.h"
#include "dump.h"
#include "parser.h"
struct one_task
{
int task_id;
int is_done;
int n_steps;
int steps_done;
int mes_done;
};
#include "one_task.h"
class runner_single
{
......@@ -36,7 +28,7 @@ class runner_single
std::string rundir;
std::string taskdir;
mc * sys;
abstract_mc * sys;
int do_next;
......@@ -64,11 +56,10 @@ class runner_single
public:
runner_single(int argc, char *argv[]);
runner_single();
~runner_single();
void start();
int start(const std::string& jobfile, double walltime, double checkpointtime, function<abstract_mc* (string &)> mccreator, int argc, char **argv);
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment