mc.cpp 4.42 KB
Newer Older
1
#include "mc.h"
2 3
namespace loadl {

Lukas Weber's avatar
wrong &  
Lukas Weber committed
4
mc::mc(const parser &p) : param{p} {
5 6
	therm_ = p.get<int>("thermalization");
	pt_sweeps_per_global_update_ = p.get<int>("pt_sweeps_per_global_update", -1);
7 8
}

9
void mc::write_output(const std::string &) {}
10

11
int mc::sweep() const {
12
	return sweep_;
Lukas Weber's avatar
Lukas Weber committed
13
}
14

15
void mc::_init() {
16
	// simple profiling support: measure the time spent for sweeps/measurements etc
17 18 19 20
	measure.register_observable("_ll_checkpoint_read_time", 1);
	measure.register_observable("_ll_checkpoint_write_time", 1);
	measure.register_observable("_ll_measurement_time", 1000);
	measure.register_observable("_ll_sweep_time", 1000);
21 22 23 24 25 26

	if(param.defined("seed")) {
		rng.reset(new random_number_generator(param.get<uint64_t>("seed")));
	} else {
		rng.reset(new random_number_generator());
	}
Lukas Weber's avatar
Lukas Weber committed
27

28
	init();
29 30
}

31
void mc::_do_measurement() {
32 33 34 35 36 37
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

	do_measurement();

	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
38 39 40

	double measurement_time =
	    (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec);
41 42 43 44
	measure.add("_ll_measurement_time", measurement_time);
	if(measurement_time > max_meas_time_) {
		max_meas_time_ = measurement_time;
	}
45 46
}

47
void mc::_do_update() {
48 49
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);
50
	sweep_++;
51

52
	do_update();
53
	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
54 55 56 57 58 59

	double sweep_time = (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec);
	measure.add("_ll_sweep_time", sweep_time);
	if(sweep_time > max_sweep_time_) {
		max_sweep_time_ = sweep_time;
	}
60 61
}

Lukas Weber's avatar
Lukas Weber committed
62
void mc::_pt_update_param(int target_rank, const std::string &param_name, double new_param) {
63
	measure.mpi_sendrecv(target_rank);
64
	pt_update_param(param_name, new_param);
65 66
}

Lukas Weber's avatar
Lukas Weber committed
67
double mc::_pt_weight_ratio(const std::string &param_name, double new_param) {
68
	double wr = pt_weight_ratio(param_name, new_param);
Lukas Weber's avatar
Lukas Weber committed
69 70 71
	return wr;
}

72 73 74 75
void mc::_write(const std::string &dir) {
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

76 77 78
	// blocks limit scopes of the dump file handles to ensure they are closed at the right time.
	{
		iodump meas_file = iodump::open_readwrite(dir + ".meas.h5");
79 80
		auto g = meas_file.get_root();
		measure.samples_write(g);
81
	}
82

83 84 85
	{
		iodump dump_file = iodump::create(dir + ".dump.h5.tmp");
		auto g = dump_file.get_root();
86

87 88
		rng->checkpoint_write(g.open_group("random_number_generator"));
		checkpoint_write(g.open_group("simulation"));
89
		measure.checkpoint_write(g.open_group("measurements"));
90

91 92 93 94
		g.write("max_checkpoint_write_time", max_checkpoint_write_time_);
		g.write("max_sweep_time", max_sweep_time_);
		g.write("max_meas_time", max_meas_time_);

95 96 97 98
		g.write("sweeps", sweep_);
		g.write("thermalization_sweeps", std::min(therm_, sweep_)); // only for convenience
	}
	rename((dir + ".dump.h5.tmp").c_str(), (dir + ".dump.h5").c_str());
99

100
	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
101 102
	double checkpoint_write_time =
	    (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec);
103 104 105 106 107 108 109 110
	measure.add("_ll_checkpoint_write_time", checkpoint_write_time);
	if(checkpoint_write_time > max_checkpoint_write_time_) {
		max_checkpoint_write_time_ = checkpoint_write_time;
	}
}

double mc::safe_exit_interval() {
	// this is more or less guesswork in an attempt to make it safe for as many cases as possible
111
	return 2 * (max_checkpoint_write_time_ + max_sweep_time_ + max_meas_time_) + 2;
112 113
}

114
bool mc::_read(const std::string &dir) {
Lukas Weber's avatar
Lukas Weber committed
115
	if(!file_exists(dir + ".dump.h5")) {
116 117
		return false;
	}
118 119 120 121 122 123

	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

	iodump dump_file = iodump::open_readonly(dir + ".dump.h5");
	auto g = dump_file.get_root();
Lukas Weber's avatar
Lukas Weber committed
124 125

	rng.reset(new random_number_generator());
126
	rng->checkpoint_read(g.open_group("random_number_generator"));
Lukas Weber's avatar
Lukas Weber committed
127
	measure.checkpoint_read(g.open_group("measurements"));
128 129 130 131
	checkpoint_read(g.open_group("simulation"));

	g.read("sweeps", sweep_);

132 133 134 135
	g.read("max_checkpoint_write_time", max_checkpoint_write_time_);
	g.read("max_sweep_time", max_sweep_time_);
	g.read("max_meas_time", max_meas_time_);

136 137 138
	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
	measure.add("_ll_checkpoint_read_time",
	            (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec));
139 140 141
	return true;
}

142
void mc::_write_output(const std::string &filename) {
143
	write_output(filename);
144 145
}

146
bool mc::is_thermalized() {
147 148 149 150
	int sweep = sweep_;
	if(pt_mode_ && pt_sweeps_per_global_update_ > 0) {
		sweep /= pt_sweeps_per_global_update_;
	}
Lukas Weber's avatar
Lukas Weber committed
151

152
	return sweep >= therm_;
153
}
154
}