mc.cpp 4.3 KB
Newer Older
1
#include "mc.h"
2
3
#include <filesystem>

4
5
namespace loadl {

6
mc::mc(const parser &p) : param{p}, measure{p.get<size_t>("binsize")} {
7
	therm_ = p.get<int>("thermalization");
Lukas Weber's avatar
Lukas Weber committed
8
	pt_sweeps_per_global_update_ = p.get<int>("pt_sweeps_per_global_update", 1);
9
10
}

11
void mc::write_output(const std::string &) {}
12

Lukas Weber's avatar
Lukas Weber committed
13
size_t mc::sweep() const {
14
	return sweep_;
Lukas Weber's avatar
Lukas Weber committed
15
}
16

17
void mc::_init() {
18
	// simple profiling support: measure the time spent for sweeps/measurements etc
19
20
	measure.register_observable("_ll_checkpoint_read_time", 1);
	measure.register_observable("_ll_checkpoint_write_time", 1);
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
	measure.add("_ll_measurement_time", measurement_time);
42
43
}

44
void mc::_do_update() {
45
46
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);
47
	sweep_++;
48

49
	do_update();
50
	clock_gettime(CLOCK_MONOTONIC_RAW, &tend);
51
52

	double sweep_time = (tend.tv_sec - tstart.tv_sec) + 1e-9 * (tend.tv_nsec - tstart.tv_nsec);
53
54
55
	if(is_thermalized()) {
		measure.add("_ll_sweep_time", sweep_time);
	}
56
57
}

Lukas Weber's avatar
Lukas Weber committed
58
void mc::_pt_update_param(int target_rank, const std::string &param_name, double new_param) {
59
	measure.mpi_sendrecv(target_rank);
60
	pt_update_param(param_name, new_param);
61
62
}

Lukas Weber's avatar
Lukas Weber committed
63
double mc::_pt_weight_ratio(const std::string &param_name, double new_param) {
64
	double wr = pt_weight_ratio(param_name, new_param);
Lukas Weber's avatar
Lukas Weber committed
65
66
67
	return wr;
}

68
69
70
71
void mc::_write(const std::string &dir) {
	struct timespec tstart, tend;
	clock_gettime(CLOCK_MONOTONIC_RAW, &tstart);

72
73
	// blocks limit scopes of the dump file handles to ensure they are closed at the right time.
	{
74
		std::error_code ec;
75
		std::filesystem::copy_file(dir + ".meas.h5", dir + ".meas.h5.tmp", std::filesystem::copy_options::overwrite_existing, ec);
76
77
78
79
		if(ec && ec != std::errc::no_such_file_or_directory) {
			throw std::system_error(ec);
		}
		iodump meas_file = iodump::open_readwrite(dir + ".meas.h5.tmp");
80
81
		auto g = meas_file.get_root();
		measure.samples_write(g);
82
	}
83

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

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

Lukas Weber's avatar
Lukas Weber committed
92
		size_t therm = therm_;
Lukas Weber's avatar
Lukas Weber committed
93
94
95
		if(pt_mode_) {
			therm *= pt_sweeps_per_global_update_;
		}
96
97
		g.write("thermalization_sweeps", std::min(sweep_, therm));
		g.write("sweeps", sweep_ - std::min(sweep_, therm));
98
	}
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
	measure.add("_ll_checkpoint_write_time", checkpoint_write_time);
104
105
}

106
107
108
// This function is called if it is certain that the *.tmp files have been completely written.
// Important for parallel tempering mode where all slaves in a chain have to write consistent dumps.
void mc::_write_finalize(const std::string &dir) {
109
110
	std::filesystem::rename(dir + ".dump.h5.tmp", dir + ".dump.h5");
	std::filesystem::rename(dir + ".meas.h5.tmp", dir + ".meas.h5");
111
112
}

113
bool mc::_read(const std::string &dir) {
114
	if(!std::filesystem::exists(dir + ".dump.h5")) {
115
116
		return false;
	}
117
118
119
120
121
122

	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
123
124

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

Lukas Weber's avatar
Lukas Weber committed
129
	size_t sweeps, therm_sweeps;
Lukas Weber's avatar
Lukas Weber committed
130
131
132
	g.read("thermalization_sweeps", therm_sweeps);
	g.read("sweeps", sweeps);
	sweep_ = sweeps + therm_sweeps;
133
134
135
136

	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));
137
138
139
	return true;
}

140
bool mc::is_thermalized() {
Lukas Weber's avatar
Lukas Weber committed
141
	size_t sweep = sweep_;
142
143
144
	if(pt_mode_ && pt_sweeps_per_global_update_ > 0) {
		sweep /= pt_sweeps_per_global_update_;
	}
Lukas Weber's avatar
Lukas Weber committed
145

146
	return sweep >= therm_;
147
}
148
}