21static double start_time = -1.0;
31void timer::init(
const char *tag) {
49 t_start = t_total = 0.0;
51 is_on = is_error =
false;
57 <<
"' error, unbalanced start/stop. Removing from statistics\n";
62double timer::start() {
73#ifdef GPU_SYNCHRONIZE_TIMERS
74 gpuStreamSynchronize(0);
86#ifdef GPU_SYNCHRONIZE_TIMERS
87 gpuStreamSynchronize(0);
91 t_total += (e - t_start);
96timer_value timer::value() {
103void timer::report(
bool print_not_timed) {
109 if (count > 0 && !is_error) {
110 if (t_total / count > 0.1) {
111 std::snprintf(line, 200,
"%-20s: %14.5f %14ld %12.5f s %9.6f\n", label.c_str(),
112 t_total, (
long)count, t_total / count, t_total / ttime);
113 }
else if (t_total / count > 1e-4) {
114 std::snprintf(line, 200,
"%-20s: %14.5f %14ld %12.5f ms %9.6f\n", label.c_str(),
115 t_total, (
long)count, 1e3 * t_total / count, t_total / ttime);
117 std::snprintf(line, 200,
"%-20s: %14.5f %14ld %12.5f μs %9.6f\n", label.c_str(),
118 t_total, (
long)count, 1e6 * t_total / count, t_total / ttime);
121 }
else if (!is_error && print_not_timed) {
122 std::snprintf(line, 200,
"%-20s: no timed calls made\n", label.c_str());
124 }
else if (is_error) {
125 std::snprintf(line, 200,
"%-20s: error:unbalanced start/stop\n", label.c_str());
131void report_timers() {
135#if defined(CUDA) || defined(HIP)
136#if defined(GPU_SYNCHRONIZE_TIMERS)
137 hila::out <<
"TIMERS: synchronized to GPU kernel execution (GPU_SYNCHRONIZE_TIMERS "
140 hila::out <<
"TIMERS: GPU_SYNCHRONIZE_TIMERS not defined, fine-grained timing "
141 "likely to be incorrect\n";
145 hila::out <<
"TIMER REPORT: total(sec) calls "
146 "time/call fraction\n";
147 hila::out <<
"------------------------------------------------------------"
148 "-----------------\n";
154 hila::out <<
"------------------------------------------------------------"
155 "-----------------\n";
170 if (start_time == -1.0)
173 clock_gettime(CLOCK_MONOTONIC, &tp);
174 return (((
double)tp.tv_sec - start_time) + 1.0e-9 * (
double)tp.tv_nsec);
178 if (start_time == -1.0) {
192static double timelimit = 0;
200 hila::out0 <<
"Time limit is " << timelimit <<
" seconds\n";
211 constexpr int timelimit_buf_size = 100;
215 const char *str = timestr.c_str();
216 char buf[timelimit_buf_size];
218 if (timestr ==
"slurm") {
220 const char cmd[] =
"squeue -h --job ${SLURM_JOB_ID} -O TimeLeft";
221 std::FILE *fp = popen(cmd,
"r");
223 if (fp && fgets(buf, timelimit_buf_size - 1, fp)) {
224 buf[timelimit_buf_size - 1] = 0;
226 for (
int i = std::strlen(buf) - 1; i >= 0 && std::isspace(buf[i]); i--)
230 hila::out0 <<
"Got time limit with command '" << cmd <<
'\n';
232 hila::out0 <<
"COULD NOT GET TIME FROM squeue COMMAND\n";
240 unsigned d{0}, h{0}, m{0}, s{0};
244 if (std::sscanf(str,
"%u-%u:%u:%u", &d, &h, &m, &s) == --nargs ||
245 std::sscanf(str,
"%u:%u:%u", &h, &m, &s) == --nargs ||
246 std::sscanf(str,
"%u:%u", &m, &s) == --nargs ||
247 std::sscanf(str,
"%u", &s) == --nargs) {
249 if (nargs < 4) d = 0;
250 if (nargs < 3) h = 0;
251 if (nargs < 2) m = 0;
253 timelimit = s + 60.0 * (m + 60.0 * (h + 24.0 * d));
254 hila::out0 <<
"Time limit is " << str <<
" = " << timelimit <<
" seconds\n";
257 hila::out0 <<
"INVALID TIMELIMIT -t ARGUMENT " << str <<
'\n';
280static volatile std::sig_atomic_t received_signal;
282void signal_handler(
int signal) {
283 received_signal = signal;
286void setup_signal_handler() {
288 std::signal(SIGUSR1, signal_handler);
292 return received_signal;
328 static double max_interval = 0.0;
329 static double previous_time = 0.0;
333 int signal = signal_status();
338 hila::out0 <<
"FINISH UP ON SIGNAL SIGUSR1\n";
340 }
else if (timelimit == 0.0) {
347 if (this_time - previous_time > max_interval)
348 max_interval = this_time - previous_time;
349 previous_time = this_time;
352 if (timelimit - this_time < max_interval + 2 * 60.0)
361 hila::out <<
"CPU TIME LIMIT, EXITING THE PROGRAM\n";
372void timestamp(
const char *msg) {
375 std::time_t ct = std::time(NULL);
378 std::string d = ctime(&ct);
379 d.resize(d.size() - 1);
387void timestamp(
const std::string &msg) {
388 hila::timestamp(msg.c_str());
This file defines all includes for HILA.
Implement hila::swap for gauge fields.
void setup_timelimit(const double secs)
Setup time limit with seconds.
int myrank()
rank of this node
std::ostream out
this is our default output file stream
std::ostream out0
This writes output only from main process (node 0)
T broadcast(T &var, int rank=0)
Broadcast the value of var to all MPI ranks from rank (default=0).
std::vector< timer * > timer_list
Timer routines - for high-resolution event timing.
void terminate(int status)