mc.cpp 4.77 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
double mc::random01() {
Lukas Weber's avatar
Lukas Weber committed
12
	return rng->random_double();
13
}
Lukas Weber's avatar
Lukas Weber committed
14

15
int mc::sweep() const {
16
	return sweep_;
Lukas Weber's avatar
Lukas Weber committed
17
}
18

19
void mc::_init() {
20
	// simple profiling support: measure the time spent for sweeps/measurements etc
21 22 23 24
	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);
25

26 27
	if(pt_mode_) {
		if(param.get<bool>("pt_statistics", false)) {
28
			measure.register_observable("_ll_pt_rank", 1);
29
		}
30
	}
Lukas Weber's avatar
Lukas Weber committed
31

32 33 34 35 36
	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
37

38
	init();
39 40
}

41
void mc::_do_measurement() {
42 43 44 45 46 47
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

	do_measurement();

	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
48 49 50

	double measurement_time =
	    (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec);
51 52 53 54
	measure.add("_ll_measurement_time", measurement_time);
	if(measurement_time > max_meas_time_) {
		max_meas_time_ = measurement_time;
	}
55 56
}

57
void mc::_do_update() {
58 59
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);
60
	sweep_++;
61

62
	do_update();
63
	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
64 65 66 67 68 69

	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;
	}
70 71
}

72 73
void mc::_pt_update_param(int target_rank, const std::string& param_name, double new_param) {
	measure.mpi_sendrecv(target_rank);
74
	pt_update_param(param_name, new_param);
75 76 77
}

void mc::pt_measure_statistics() {
78 79 80 81 82
	if(param.get<bool>("pt_statistics", false)) {
		int rank;
		MPI_Comm_rank(MPI_COMM_WORLD, &rank);
		measure.add("_ll_pt_rank", rank);
	}
83 84
}

85 86
double mc::_pt_weight_ratio(const std::string& param_name, double new_param) {
	double wr = pt_weight_ratio(param_name, new_param);
Lukas Weber's avatar
Lukas Weber committed
87 88 89
	return wr;
}

90 91 92 93
void mc::_write(const std::string &dir) {
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

94 95 96
	// 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");
97 98
		auto g = meas_file.get_root();
		measure.samples_write(g);
99
	}
100

101 102 103
	{
		iodump dump_file = iodump::create(dir + ".dump.h5.tmp");
		auto g = dump_file.get_root();
104

105 106
		rng->checkpoint_write(g.open_group("random_number_generator"));
		checkpoint_write(g.open_group("simulation"));
107
		measure.checkpoint_write(g.open_group("measurements"));
108

109 110 111 112
		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_);

113 114 115 116
		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());
117

118
	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
119 120
	double checkpoint_write_time =
	    (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec);
121 122 123 124 125 126 127 128
	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
129
	return 2 * (max_checkpoint_write_time_ + max_sweep_time_ + max_meas_time_) + 2;
130 131
}

132
bool mc::_read(const std::string &dir) {
Lukas Weber's avatar
Lukas Weber committed
133
	if(!file_exists(dir + ".dump.h5")) {
134 135
		return false;
	}
136 137 138 139 140 141

	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
142 143

	rng.reset(new random_number_generator());
144
	rng->checkpoint_read(g.open_group("random_number_generator"));
Lukas Weber's avatar
Lukas Weber committed
145
	measure.checkpoint_read(g.open_group("measurements"));
146 147 148 149
	checkpoint_read(g.open_group("simulation"));

	g.read("sweeps", sweep_);

150 151 152 153
	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_);

154 155 156
	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));
157 158 159
	return true;
}

160
void mc::_write_output(const std::string &filename) {
161
	write_output(filename);
162 163
}

164
bool mc::is_thermalized() {
165 166 167 168
	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
169

170
	return sweep >= therm_;
171
}
172
}