2019-06-19 14:34:30 +02:00
|
|
|
/*
|
|
|
|
* Copyright © 2004-2011 Ondra Kamenik
|
|
|
|
* Copyright © 2019 Dynare Team
|
|
|
|
*
|
|
|
|
* This file is part of Dynare.
|
|
|
|
*
|
|
|
|
* Dynare is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Dynare is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
|
|
#include "journal.hh"
|
|
|
|
#include "kord_exception.hh"
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
#include <iomanip>
|
|
|
|
#include <cmath>
|
2019-01-04 16:29:57 +01:00
|
|
|
#include <ctime>
|
2019-03-06 18:40:19 +01:00
|
|
|
#include <limits>
|
2019-04-01 15:10:37 +02:00
|
|
|
#include <thread>
|
2019-01-04 16:29:57 +01:00
|
|
|
|
2019-04-01 11:16:04 +02:00
|
|
|
#ifndef _WIN32
|
2019-03-05 18:35:35 +01:00
|
|
|
# include <sys/time.h> // For getrusage()
|
|
|
|
# include <sys/resource.h> // For getrusage()
|
|
|
|
# include <sys/utsname.h> // For uname()
|
|
|
|
# include <cstdlib> // For getloadavg()
|
|
|
|
# include <unistd.h> // For sysconf()
|
2019-04-01 16:14:24 +02:00
|
|
|
# ifdef __APPLE__
|
|
|
|
# include <sys/types.h>
|
|
|
|
# include <sys/sysctl.h>
|
|
|
|
# endif
|
2019-03-05 18:35:35 +01:00
|
|
|
#else
|
2019-01-04 16:29:57 +01:00
|
|
|
# ifndef NOMINMAX
|
2019-03-05 18:35:35 +01:00
|
|
|
# define NOMINMAX // Do not define "min" and "max" macros
|
2019-01-04 16:29:57 +01:00
|
|
|
# endif
|
2019-03-05 18:35:35 +01:00
|
|
|
# include <windows.h> // For GlobalMemoryStatus()
|
2019-01-04 16:29:57 +01:00
|
|
|
#endif
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
const std::chrono::time_point<std::chrono::high_resolution_clock> SystemResources::start = std::chrono::high_resolution_clock::now();
|
2019-01-04 16:29:57 +01:00
|
|
|
|
2019-04-01 16:14:24 +02:00
|
|
|
#ifndef _WIN32
|
2019-03-05 18:35:35 +01:00
|
|
|
long
|
2019-01-04 16:29:57 +01:00
|
|
|
SystemResources::pageSize()
|
|
|
|
{
|
|
|
|
return sysconf(_SC_PAGESIZE);
|
|
|
|
}
|
2019-03-05 18:35:35 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
long
|
2019-04-01 16:14:24 +02:00
|
|
|
SystemResources::availableMemory()
|
2019-03-05 18:35:35 +01:00
|
|
|
{
|
2019-04-01 11:20:28 +02:00
|
|
|
#if !defined(_WIN32) && !defined(__APPLE__)
|
2019-04-01 16:14:24 +02:00
|
|
|
return sysconf(_SC_AVPHYS_PAGES)*pageSize();
|
2019-04-01 11:20:28 +02:00
|
|
|
#elif defined(__APPLE__)
|
2019-04-01 13:16:43 +02:00
|
|
|
unsigned long usermem = 0;
|
|
|
|
size_t len = sizeof usermem;
|
|
|
|
static int mib[2] = { CTL_HW, HW_USERMEM };
|
|
|
|
int retval = sysctl(mib, 2, &usermem, &len, NULL, 0);
|
|
|
|
if (retval == 0)
|
2019-04-01 16:14:24 +02:00
|
|
|
return static_cast<long>(usermem);
|
2019-04-01 13:16:43 +02:00
|
|
|
return 0;
|
2019-04-01 16:14:24 +02:00
|
|
|
#else // _WIN32
|
2019-03-05 18:35:35 +01:00
|
|
|
MEMORYSTATUS memstat;
|
|
|
|
GlobalMemoryStatus(&memstat);
|
2019-04-01 16:14:24 +02:00
|
|
|
return memstat.dwAvailPhys;
|
2019-03-05 18:35:35 +01:00
|
|
|
#endif
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
SystemResources::SystemResources()
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
auto now = std::chrono::high_resolution_clock::now();
|
|
|
|
std::chrono::duration<double> duration = now - start;
|
|
|
|
elapsed = duration.count();
|
2019-01-04 16:29:57 +01:00
|
|
|
|
2019-04-01 11:16:04 +02:00
|
|
|
#ifndef _WIN32
|
2019-01-04 16:29:57 +01:00
|
|
|
struct rusage rus;
|
|
|
|
getrusage(RUSAGE_SELF, &rus);
|
|
|
|
utime = rus.ru_utime.tv_sec+rus.ru_utime.tv_usec*1.0e-6;
|
|
|
|
stime = rus.ru_stime.tv_sec+rus.ru_stime.tv_usec*1.0e-6;
|
|
|
|
idrss = rus.ru_idrss;
|
2019-04-01 16:14:24 +02:00
|
|
|
majflt = rus.ru_majflt * pageSize();
|
2019-01-04 16:29:57 +01:00
|
|
|
#else
|
2019-03-06 18:40:19 +01:00
|
|
|
utime = std::numeric_limits<double>::quiet_NaN();
|
|
|
|
stime = std::numeric_limits<double>::quiet_NaN();
|
2019-01-04 16:29:57 +01:00
|
|
|
idrss = -1;
|
|
|
|
majflt = -1;
|
|
|
|
#endif
|
|
|
|
|
2019-04-01 11:16:04 +02:00
|
|
|
#ifndef _WIN32
|
2019-01-04 16:29:57 +01:00
|
|
|
getloadavg(&load_avg, 1);
|
|
|
|
#else
|
2019-03-06 18:40:19 +01:00
|
|
|
load_avg = std::numeric_limits<double>::quiet_NaN();
|
2019-01-04 16:29:57 +01:00
|
|
|
#endif
|
|
|
|
|
2019-04-01 16:14:24 +02:00
|
|
|
mem_avail = availableMemory();
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-03-05 18:35:35 +01:00
|
|
|
SystemResources::diff(const SystemResources &pre)
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
|
|
|
utime -= pre.utime;
|
|
|
|
stime -= pre.stime;
|
|
|
|
elapsed -= pre.elapsed;
|
|
|
|
idrss -= pre.idrss;
|
|
|
|
majflt -= pre.majflt;
|
|
|
|
}
|
|
|
|
|
2019-06-11 16:45:09 +02:00
|
|
|
// JournalRecord::operator<<() symmetry code
|
2019-01-04 16:29:57 +01:00
|
|
|
JournalRecord &
|
|
|
|
JournalRecord::operator<<(const IntSequence &s)
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
operator<<('[');
|
2019-01-04 16:29:57 +01:00
|
|
|
for (int i = 0; i < s.size(); i++)
|
|
|
|
{
|
|
|
|
operator<<(s[i]);
|
|
|
|
if (i < s.size()-1)
|
2019-03-05 18:35:35 +01:00
|
|
|
operator<<(',');
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
2019-03-05 18:35:35 +01:00
|
|
|
operator<<(']');
|
2019-01-04 16:29:57 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-03-05 18:35:35 +01:00
|
|
|
JournalRecord::writeFloatTabular(std::ostream &s, double d, int width)
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
// Number of digits of integer part
|
|
|
|
int intdigits = std::max(static_cast<int>(std::floor(log10(d))+1), 1);
|
|
|
|
|
|
|
|
int prec = std::max(width - 1 - intdigits, 0);
|
|
|
|
s << std::fixed << std::setw(width) << std::setprecision(prec) << d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
JournalRecord::writePrefix(const SystemResources &f)
|
|
|
|
{
|
|
|
|
constexpr double mb = 1024*1024;
|
|
|
|
std::ostringstream s;
|
|
|
|
s << std::setfill('0');
|
|
|
|
writeFloatTabular(s, f.elapsed, 7);
|
2019-12-20 14:36:20 +01:00
|
|
|
s << u8"│" << recChar << std::setw(5) << ord << u8"│";
|
2019-03-05 18:35:35 +01:00
|
|
|
writeFloatTabular(s, f.load_avg, 3);
|
2019-04-23 18:57:52 +02:00
|
|
|
s << u8"│";
|
2019-04-01 16:14:24 +02:00
|
|
|
writeFloatTabular(s, f.mem_avail/mb, 5);
|
2019-04-23 18:57:52 +02:00
|
|
|
s << u8"│ │ ";
|
2019-01-04 16:29:57 +01:00
|
|
|
for (int i = 0; i < 2*journal.getDepth(); i++)
|
2019-03-05 18:35:35 +01:00
|
|
|
s << ' ';
|
|
|
|
prefix = s.str();
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-03-05 18:35:35 +01:00
|
|
|
JournalRecordPair::writePrefixForEnd(const SystemResources &f)
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
constexpr double mb = 1024*1024;
|
|
|
|
SystemResources difnow;
|
2019-01-04 16:29:57 +01:00
|
|
|
difnow.diff(f);
|
2019-03-05 18:35:35 +01:00
|
|
|
std::ostringstream s;
|
|
|
|
s << std::setfill('0');
|
|
|
|
writeFloatTabular(s, f.elapsed+difnow.elapsed, 7);
|
2019-04-23 18:57:52 +02:00
|
|
|
s << u8"│E" << std::setw(5) << ord << u8"│";
|
2019-03-05 18:35:35 +01:00
|
|
|
writeFloatTabular(s, difnow.load_avg, 3);
|
2019-04-23 18:57:52 +02:00
|
|
|
s << u8"│";
|
2019-04-01 16:14:24 +02:00
|
|
|
writeFloatTabular(s, difnow.mem_avail/mb, 5);
|
2019-04-23 18:57:52 +02:00
|
|
|
s << u8"│";
|
2019-04-01 16:14:24 +02:00
|
|
|
writeFloatTabular(s, difnow.majflt/mb, 6);
|
2019-04-23 18:57:52 +02:00
|
|
|
s << u8"│ ";
|
2019-01-04 16:29:57 +01:00
|
|
|
for (int i = 0; i < 2*journal.getDepth(); i++)
|
2019-03-05 18:35:35 +01:00
|
|
|
s << ' ';
|
|
|
|
prefix_end = s.str();
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
JournalRecordPair::~JournalRecordPair()
|
|
|
|
{
|
|
|
|
journal.decrementDepth();
|
|
|
|
writePrefixForEnd(flash);
|
|
|
|
journal << prefix_end;
|
|
|
|
journal << mes;
|
2019-02-06 15:50:01 +01:00
|
|
|
journal << std::endl;
|
2019-01-04 16:29:57 +01:00
|
|
|
journal.flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
JournalRecord &
|
|
|
|
endrec(JournalRecord &rec)
|
|
|
|
{
|
|
|
|
rec.journal << rec.prefix;
|
|
|
|
rec.journal << rec.mes;
|
2019-02-06 15:50:01 +01:00
|
|
|
rec.journal << std::endl;
|
2019-01-04 16:29:57 +01:00
|
|
|
rec.journal.flush();
|
|
|
|
rec.journal.incrementOrd();
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Journal::printHeader()
|
|
|
|
{
|
2019-06-19 14:34:30 +02:00
|
|
|
*this << "Dynare++ v. " << VERSION << '\n'
|
|
|
|
<< '\n'
|
|
|
|
<< u8"Copyright © 2004-2011 Ondra Kamenik\n"
|
|
|
|
<< u8"Copyright © 2019 Dynare Team\n"
|
|
|
|
<< "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under the GNU GPL,"
|
|
|
|
<< "version 3 or later (see https://www.gnu.org/licenses/gpl.html)\n"
|
2019-03-05 18:35:35 +01:00
|
|
|
<< "\n\n"
|
|
|
|
<< "System info: ";
|
2019-04-01 11:16:04 +02:00
|
|
|
#ifndef _WIN32
|
2019-01-04 16:29:57 +01:00
|
|
|
utsname info;
|
|
|
|
uname(&info);
|
2019-03-05 18:35:35 +01:00
|
|
|
*this << info.sysname << " " << info.release << " " << info.version << " "
|
2019-04-01 15:10:37 +02:00
|
|
|
<< info.machine;
|
2019-01-04 16:29:57 +01:00
|
|
|
#else
|
2019-04-01 15:10:37 +02:00
|
|
|
*this << "Windows";
|
2019-01-04 16:29:57 +01:00
|
|
|
#endif
|
2019-04-01 15:10:37 +02:00
|
|
|
*this << ", processors online: " << std::thread::hardware_concurrency()
|
|
|
|
<< "\n\nStart time: ";
|
2019-03-05 18:35:35 +01:00
|
|
|
std::time_t t = std::time(nullptr);
|
|
|
|
*this << std::put_time(std::localtime(&t), "%c %Z")
|
|
|
|
<< "\n\n"
|
2019-04-23 18:57:52 +02:00
|
|
|
<< u8" ┌────╼ elapsed time (seconds) \n"
|
|
|
|
<< u8" │ ┌────╼ record unique identifier \n"
|
|
|
|
<< u8" │ │ ┌────╼ load average \n"
|
|
|
|
<< u8" │ │ │ ┌────╼ available memory (MB) \n"
|
|
|
|
<< u8" │ │ │ │ ┌─────╼ major faults (MB)\n"
|
|
|
|
<< u8" │ │ │ │ │ \n"
|
|
|
|
<< u8" ╽ ╽ ╽ ╽ ╽ \n";
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|