mc.cpp 4.71 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
	if(pt_mode_) {
		if(param.get<bool>("pt_statistics", false)) {
24
			measure.register_observable("_ll_pt_rank", 1);
25
		}
26
	}
Lukas Weber's avatar
Lukas Weber committed
27

28 29 30 31 32
	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
33

34
	init();
35 36
}

37
void mc::_do_measurement() {
38 39 40 41 42 43
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

	do_measurement();

	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
44 45 46

	double measurement_time =
	    (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec);
47 48 49 50
	measure.add("_ll_measurement_time", measurement_time);
	if(measurement_time > max_meas_time_) {
		max_meas_time_ = measurement_time;
	}
51 52
}

53
void mc::_do_update() {
54 55
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);
56
	sweep_++;
57

58
	do_update();
59
	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
60 61 62 63 64 65

	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;
	}
66 67
}

Lukas Weber's avatar
Lukas Weber committed
68
void mc::_pt_update_param(int target_rank, const std::string &param_name, double new_param) {
69
	measure.mpi_sendrecv(target_rank);
70
	pt_update_param(param_name, new_param);
71 72 73
}

void mc::pt_measure_statistics() {
74 75 76 77 78
	if(param.get<bool>("pt_statistics", false)) {
		int rank;
		MPI_Comm_rank(MPI_COMM_WORLD, &rank);
		measure.add("_ll_pt_rank", rank);
	}
79 80
}

Lukas Weber's avatar
Lukas Weber committed
81
double mc::_pt_weight_ratio(const std::string &param_name, double new_param) {
82
	double wr = pt_weight_ratio(param_name, new_param);
Lukas Weber's avatar
Lukas Weber committed
83 84 85
	return wr;
}

86 87 88 89
void mc::_write(const std::string &dir) {
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

90 91 92
	// 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");
93 94
		auto g = meas_file.get_root();
		measure.samples_write(g);
95
	}
96

97 98 99
	{
		iodump dump_file = iodump::create(dir + ".dump.h5.tmp");
		auto g = dump_file.get_root();
100

101 102
		rng->checkpoint_write(g.open_group("random_number_generator"));
		checkpoint_write(g.open_group("simulation"));
103
		measure.checkpoint_write(g.open_group("measurements"));
104

105 106 107 108
		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_);

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

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

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

	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
138 139

	rng.reset(new random_number_generator());
140
	rng->checkpoint_read(g.open_group("random_number_generator"));
Lukas Weber's avatar
Lukas Weber committed
141
	measure.checkpoint_read(g.open_group("measurements"));
142 143 144 145
	checkpoint_read(g.open_group("simulation"));

	g.read("sweeps", sweep_);

146 147 148 149
	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_);

150 151 152
	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));
153 154 155
	return true;
}

156
void mc::_write_output(const std::string &filename) {
157
	write_output(filename);
158 159
}

160
bool mc::is_thermalized() {
161 162 163 164
	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
165

166
	return sweep >= therm_;
167
}
168
}