Commit a786fa04 authored by lw100917's avatar lw100917
Browse files

switch to cmake and make it a real library

parent 00f1461e
cmake_minimum_required(VERSION 2.6)
project(load_leveller)
find_package(MPI REQUIRED)
set(CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O3 -std=c++11 -pedantic ${MPI_LINK_FLAGS} ${MPI_COMPILE_FLAGS}")
include_directories(${MPI_INCLUDE_PATH})
option(MEASUREMENTS_APPEND "Use append mode for writing measurements" OFF)
option(DUMP_BUFFER "dump uses buffered writeout" OFF)
if(MEASUREMENTS_APPEND)
add_definitions(-DMCL_MEASUREMENTS_APPEND=1)
endif()
if(DUMP_BUFFER)
add_definitions(-DMCL_DUMP_BUFFER=1)
endif()
set(SRCs
dump.cpp
evalable.cpp
measurements.cpp
observable.cpp
parser.cpp
random.cpp
runner.cpp
merge.cpp
mc.cpp
#runner_single.cpp
runner_pt.cpp
)
add_library(load_leveller STATIC ${SRCs})
target_link_libraries(load_leveller ${MPI_LIBRARIES})
SET(MCPREFIX "$ENV{HOME}/mc/" CACHE PATH "Prefix prepended to
install directories")
SET(CMAKE_INSTALL_PREFIX "${MCPREFIX}" CACHE INTERNAL "Prefix
prepended to install directories" FORCE)
install(TARGETS load_leveller DESTINATION .)
......@@ -5,12 +5,6 @@
#define MCL_DUMP_BUFFER 0
#endif
#if MCL_DUMP_BUFFER
#warning MCL_DUMP_BUFFER=1: dump uses buffered writeout
#else
#warning MCL_DUMP_BUFFER=0: no buffering in dump writeout
#endif
#define DUMP_APPEND 0
#include <iostream>
......@@ -18,9 +12,6 @@
#include <cstring>
#include <string>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include "types.h"
class odump
......
#include "evalable.h"
#include <sstream>
void evalable :: mean(valarray<double>& v) {
v=mean_v[0];
......
#ifndef MCL_VECTOREVALABLE_H
#define MCL_VECTOREVALABLE_H
#include <iostream>
#include <sstream>
#include <cmath>
#include <string>
#include <vector>
#include <valarray>
......
#ifdef MCL_PT
#include "runner_pt.h"
#else
#ifdef MCL_SINGLE
#include "runner_single.h"
#else
#include "runner.h"
#endif
#endif
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
int main ( int argc, char *argv[] )
{
#ifdef MCL_PT
runner_pt my_run(argc,argv);
#else
#ifdef MCL_SINGLE
if(argc < 2)
{
cerr << "Usage: " << argv[0] <<" jobfile [walltime] [checkpointtime] "<< endl;
return 1;
}
runner_single my_run(argc,argv);
#else
runner my_run(argc,argv);
#endif
#endif
my_run.start();
return 0;
}
#include "mc.h"
mc :: mc (string dir) {
param_init(dir);
}
mc :: ~mc() {
random_clear();
}
void mc::random_init() {
if (param.defined("SEED"))
rng = new randomnumbergenerator(param.value_of<luint>("SEED"));
else
rng = new randomnumbergenerator();
have_random=true;
}
void mc::param_init(string dir) {
param.read_file(dir);
}
void mc::random_write(odump& d) {
rng->write(d);
}
void mc::seed_write(string fn) {
ofstream s;
s.open(fn.c_str());
s << rng->seed()<<endl;s.close();
}
void mc::random_read(idump& d) {
rng = new randomnumbergenerator();
have_random=true;
rng->read(d);
}
void mc::random_clear() {
if(have_random) {
delete rng;
have_random=false;
}
}
double mc::random01() {
return rng->d();
}
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include "measurements.h"
#include "random.h"
#include "parser.h"
#include "types.h"
using namespace std;
class mc
{
private:
bool have_random = false;
void param_init(string dir);
void random_clear();
protected:
void random_write(odump& d);
void seed_write(string fn);
void random_read(idump& d);
parser param;
public:
double random01();
int sweep;
randomnumbergenerator * rng;
void random_init();
virtual void init() = 0;
virtual void do_update() = 0;
virtual void do_measurement() = 0;
virtual void write(string) = 0;
virtual bool read(string) = 0;
virtual void write_output(string) = 0;
virtual bool is_thermalized() = 0;
measurements measure;
mc(string dir);
virtual ~mc();
};
#ifndef MC_PT_H
#define MC_PT_H
#include <iostream>
#include <vector>
#include <string>
#include "measurements.h"
#include "random.h"
#include "parser.h"
#include "types.h"
using namespace std;
class mc_pt
{
private:
int Lx;
int Ly;
vector<double> Tvec;
double T;
int therm;
int sweep;
int pt_spacing;
int label;
vector<int> spin;
public:
parser param;
void param_init(string dir) {param.read_file(dir);}
bool have_random;
randomnumbergenerator * rng;
void random_init() {if (param.defined("SEED"))
rng = new randomnumbergenerator(param.value_of<luint>("SEED"));
else
rng = new randomnumbergenerator();
have_random=true;
}
void random_write(odump& d) {rng->write(d);}
void seed_write(string fn) {ofstream s; s.open(fn.c_str()); s << rng->seed()<<endl;s.close();}
void random_read(idump& d) {rng = new randomnumbergenerator();have_random=true;rng->read(d);}
void random_clear() { if (have_random) {delete rng;have_random=false;} }
double random01() {return rng->d();}
void init();
void do_update();
void do_measurement();
void write(string);
bool read(string);
void write_output(string,int);
bool is_thermalized();
bool request_global_update();
void change_parameter(int);
void change_to(int);
double get_weight(int);
int get_label();
int myrep;
vector<measurements> measure;
mc_pt(string);
~mc_pt();
};
#endif
#include "measurements.h"
#include <sstream>
void measurements :: add_observable(std::string name)
{
......
......@@ -5,15 +5,6 @@
#define MCL_MEASUREMENTS_APPEND 0
#endif
#if MCL_MEASUREMENTS_APPEND
#warning MCL_MEASUREMENTS_APPEND=1: measurements will be written in append mode
#else
#warning MCL_MEASUREMENTS_APPEND=0: observable I/O involve full data sets
#endif
#include <iostream>
#include <fstream>
#include <cmath>
#include <string>
#include <vector>
#include <map>
......
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "mc.h"
#include "measurements.h"
#include "dump.h"
#include "parser.h"
using namespace std;
int merge(function<mc* (string&)> mccreator, int argc, char* argv[]) {
if (argc==1) {
cout << " usage: "<< argv[0] <<" jobfilename [-s number_of_bins_to_be_skipped] [-t min_task max_task] [-r min_run max_run]" << endl;
exit(1);
}
std::string jobfile(argv[1]);
int task_min=1;
int task_max=-1;
int run_min=1;
int run_max=-1;
int skipbins=0;
int rarg=2;
while (argc>rarg) {
if (argv[rarg][0]=='s' || argv[rarg][1]=='s') {
rarg++;
skipbins=atoi(argv[rarg]);
rarg++;
}
else if (argv[rarg][0]=='t' || argv[rarg][1]=='t') {
rarg++;
task_min=atoi(argv[rarg]);
rarg++;
task_max=atoi(argv[rarg]);
rarg++;
}
else if (argv[rarg][0]=='r' || argv[rarg][1]=='r') {
rarg++;
run_min=atoi(argv[rarg]);
rarg++;
run_max=atoi(argv[rarg]);
rarg++;
}
else {
cout<<"unknown option "<<argv[rarg]<<endl;
exit(1);
}
};
cout <<"Merging "<<jobfile;
if (task_max==-1) {
cout << " all task";
}
else {
cout <<" task " <<task_min << " to " << task_max;
}
if (run_max==-1) {
cout << " all runs";
}
else {
cout <<" run " <<run_min << " to " << run_max;
}
if (skipbins) cout << " skipping the first " << skipbins <<" bins";
cout << endl;
parser parsedfile(jobfile+".alltasks");
std::vector<string> taskfiles;
taskfiles= parsedfile.return_vector< string >("@taskfiles");
std::string masterfile = parsedfile.value_or_default<string>("masterfile",jobfile+".master");
if (task_max==-1) task_max=taskfiles.size();
for (int i=task_min-1;i<task_max;++i) {
std::string taskfile = taskfiles[i];
parser cfg(taskfile);
std::string taskdir = cfg.value_of("taskdir");
std::stringstream rb; rb << taskdir << "/run" << run_min << ".";
std::string rundir = rb.str();
mc* sys = mccreator(taskfile);
if ((*sys).read(rundir)) {
if ((*sys).measure.merge(rundir,skipbins)) cout << rundir <<endl;
if (1) {
int run_counter=run_min+1;
bool success=true;
while (success && ((run_max==-1) || (run_counter<=run_max))) {
stringstream b;b<<taskdir<<"/run"<<run_counter<<".";
success=(*sys).measure.merge(b.str(),skipbins);
if (success) cout << b.str() <<endl;
++run_counter;
}
std::stringstream mfb;
if (run_max==-1) {
mfb << taskdir << ".";
}
else {
if (run_min==run_max) {
mfb << taskdir <<"."<<run_min<<".";
}
else {
mfb << taskdir <<"."<<run_min<<"."<<run_max<<".";
}
}
if (skipbins) mfb <<"s"<<skipbins<<".";
mfb <<"out";
(*sys).write_output(mfb.str());
}
}
delete sys;
}
return 0;
}
#pragma once
#include <functional>
#include "mc.h"
int merge(function<mc* (string&)> mccreator,int argc, char *argv[]);
#include "parser.h"
#include <cstdlib>
#include <fstream>
#include <iostream>
parser :: parser()
{
......
#ifndef MY_PARSER_H
#define MY_PARSER_H
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <cstdlib>
#include <map>
#include "types.h"
......
......@@ -7,7 +7,6 @@
#define MCL_RNG_MT
#ifdef MCL_RNG_MT
#warning using RNG: MT (MersenneTwistor)
#include "MersenneTwister.h"
class randomnumbergenerator
{
......@@ -29,7 +28,6 @@ private:
#endif
#ifdef MCL_RNG_SPRNG_4
#warning using RNG: SPRNG 4
#include "sprng_cpp.h"
class randomnumbergenerator
{
......@@ -52,7 +50,6 @@ private:
#ifdef MCL_RNG_BOOST
#warning RNG: BOOST
#include <boost/random.hpp>
class randomnumbergenerator
{
......
#include "runner.h"
#include "merge.h"
runner::runner(int argc, char *argv[])
runner::runner()
{
}
runner :: ~runner()
{
STATUS.close();
delete sys;
}
int runner :: start(int argc, char *argv[], function<mc* (string &)> 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);
sys = NULL;
my_mccreator=mccreator;
jobfile = argv[1];
parser parsedfile(jobfile);
if (argc>2) walltime=atof(argv[2]);
......@@ -22,28 +42,20 @@ runner::runner(int argc, char *argv[])
chktime*=60;
}
}
taskfiles= parsedfile.return_vector< string >("@taskfiles");
time_start = MPI_Wtime();
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);
}
STATUS.open(statusfile.c_str(), std::ios::out|std::ios::app);
runner :: ~runner()
{
(*STATUS).close();
delete STATUS;
delete sys;
}
void runner :: start()
{
if(my_rank == MASTER) {
M_read();
M_wait();
}
else what_is_next(S_IDLE);
return 0;
}
bool runner :: is_chkpt_time()
......@@ -76,7 +88,7 @@ void runner :: M_update(int node)
int node_status;
MPI_Status stat;
MPI_Recv(&node_status, 1, MPI_INT, node, T_STATUS, MPI_COMM_WORLD, &stat);
//(*STATUS) << my_rank << ": Status " << node_status << " from " << node << "\n";
//STATUS << my_rank << ": Status " << node_status << " from " << node << "\n";
if (node_status == S_IDLE) {
if(time_is_up()) M_send_action(A_EXIT,node);
else {
......@@ -111,7 +123,7 @@ void runner :: M_update(int node)
void runner :: M_send_action(int action, int to)
{
//(*STATUS) << my_rank << ": Action "<<action<<" to " << to << "\n";
//STATUS << my_rank << ": Action "<<action<<" to " << to << "\n";
MPI_Send(&action, 1, MPI_INT, to, T_ACTION, MPI_COMM_WORLD);
if(action == A_EXIT) N_exit ++;
}
......@@ -187,24 +199,24 @@ void runner :: M_end_of_run()
std::ofstream rfile(rfilename.c_str());
rfile << "restart me\n";
rfile.close();
(*STATUS) << my_rank << ": Restart needed" << "\n";
STATUS << my_rank << ": Restart needed" << "\n";
}
M_report();
MPI_Finalize();
(*STATUS) << my_rank << ": MPI finalized" << "\n";
STATUS << my_rank << ": MPI finalized" << "\n";
exit(0);
}
void runner :: M_report()
{
for(uint i = 0; i < tasks.size(); i ++) {
(*STATUS)
STATUS
<< tasks[i].task_id << "\t"
<< int(tasks[i].mes_done/(double)(tasks[i].n_steps)*100)<<"%\t"
<< tasks[i].steps_done << "\t"
<< tasks[i].mes_done << "\n";
}
(*STATUS) << "\n";
STATUS << "\n";
}
void runner :: what_is_next(int status)
......@@ -251,12 +263,13 @@ void runner :: run()
my_task.steps_done = 0;
delete sys;
std::string taskfile = taskfiles[my_task.task_id];
sys = new mc(taskfile);
sys = my_mccreator(taskfile);
if ((*sys).measure.read(my_rundir) && (*sys).read(my_rundir)) {
(*STATUS) << my_rank << ": L " << my_rundir << "\n";
STATUS << my_rank << ": L " << my_rundir << "\n";
}
else {
(*STATUS) << my_rank << ": I " << my_rundir << "\n";
STATUS << my_rank << ": I " << my_rundir << "\n";
(*sys).random_init();
(*sys).init();
checkpointing();
}
......@@ -282,7 +295,7 @@ void runner :: run()
my_task.steps_done = 0;
}
}
(*STATUS) << my_rank << ": F " << my_rundir << "\n";
STATUS << my_rank << ": F " << my_rundir << "\n";
checkpointing();
what_is_next(S_FINISHED);
}
......@@ -291,7 +304,7 @@ void runner :: checkpointing()
{
(*sys).write(my_rundir);
(*sys).measure.write(my_rundir);
(*STATUS) << my_rank << ": C " << my_rundir << "\n";
STATUS << my_rank << ": C " << my_rundir << "\n";
}
void runner :: merge_measurements()
......@@ -303,19 +316,19 @@ void runner :: merge_measurements()
stringstream b;b<<my_taskdir<<"/run"<<run_counter<<".";
success=(*sys).measure.merge(b.str());
if (