2019-06-19 14:34:30 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2004 Ondra Kamenik
|
2020-10-15 17:14:53 +02:00
|
|
|
|
* Copyright © 2019-2020 Dynare Team
|
2019-06-19 14:34:30 +02:00
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
|
|
|
|
// Resource usage journal
|
|
|
|
|
|
|
|
|
|
#ifndef JOURNAL_H
|
|
|
|
|
#define JOURNAL_H
|
|
|
|
|
|
2019-01-08 16:09:25 +01:00
|
|
|
|
#include "int_sequence.hh"
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
|
|
|
|
#include <iostream>
|
2019-03-05 18:35:35 +01:00
|
|
|
|
#include <sstream>
|
2019-01-04 16:29:57 +01:00
|
|
|
|
#include <fstream>
|
2019-03-05 18:35:35 +01:00
|
|
|
|
#include <string>
|
|
|
|
|
#include <chrono>
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
|
/* Implement static methods for accessing some system resources. An instance of
|
|
|
|
|
this class is a photograph of these resources at the time of instantiation. */
|
|
|
|
|
struct SystemResources
|
2019-01-04 16:29:57 +01:00
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
// The starting time of the executable
|
|
|
|
|
static const std::chrono::time_point<std::chrono::high_resolution_clock> start;
|
|
|
|
|
|
2019-04-01 16:14:24 +02:00
|
|
|
|
#ifndef _WIN32
|
2019-03-05 18:35:35 +01:00
|
|
|
|
static long pageSize();
|
2019-04-01 16:14:24 +02:00
|
|
|
|
#endif
|
2019-03-05 18:35:35 +01:00
|
|
|
|
static long availableMemory();
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
|
|
|
|
double load_avg;
|
2019-04-01 16:14:24 +02:00
|
|
|
|
long mem_avail;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
double utime;
|
|
|
|
|
double stime;
|
|
|
|
|
double elapsed;
|
2019-03-05 18:35:35 +01:00
|
|
|
|
long idrss;
|
|
|
|
|
long majflt;
|
|
|
|
|
|
|
|
|
|
SystemResources();
|
|
|
|
|
void diff(const SystemResources &pre);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
};
|
|
|
|
|
|
2019-02-06 15:50:01 +01:00
|
|
|
|
class Journal : public std::ofstream
|
2019-01-04 16:29:57 +01:00
|
|
|
|
{
|
2020-10-15 17:14:53 +02:00
|
|
|
|
int ord{0};
|
|
|
|
|
int depth{0};
|
2019-01-04 16:29:57 +01:00
|
|
|
|
public:
|
2019-03-05 18:35:35 +01:00
|
|
|
|
explicit Journal(const std::string &fname)
|
2020-10-15 17:14:53 +02:00
|
|
|
|
: std::ofstream(fname)
|
2019-01-04 16:29:57 +01:00
|
|
|
|
{
|
|
|
|
|
printHeader();
|
|
|
|
|
}
|
2020-10-15 17:14:53 +02:00
|
|
|
|
/* Constructor that does not initialize the std::ofstream. To be used when an
|
|
|
|
|
on-disk journal is not wanted. */
|
|
|
|
|
Journal() = default;
|
|
|
|
|
Journal &operator=(Journal &&) = default;
|
2019-01-09 16:26:42 +01:00
|
|
|
|
~Journal() override
|
2019-01-04 16:29:57 +01:00
|
|
|
|
{
|
|
|
|
|
flush();
|
|
|
|
|
}
|
|
|
|
|
void printHeader();
|
|
|
|
|
void
|
|
|
|
|
incrementOrd()
|
|
|
|
|
{
|
|
|
|
|
ord++;
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
getOrd() const
|
|
|
|
|
{
|
|
|
|
|
return ord;
|
|
|
|
|
}
|
|
|
|
|
void
|
|
|
|
|
incrementDepth()
|
|
|
|
|
{
|
|
|
|
|
depth++;
|
|
|
|
|
}
|
|
|
|
|
void
|
|
|
|
|
decrementDepth()
|
|
|
|
|
{
|
|
|
|
|
depth--;
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
getDepth() const
|
|
|
|
|
{
|
|
|
|
|
return depth;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class JournalRecord;
|
2019-03-05 18:35:35 +01:00
|
|
|
|
JournalRecord &endrec(JournalRecord &);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
|
|
|
|
class JournalRecord
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
char recChar;
|
|
|
|
|
int ord;
|
|
|
|
|
public:
|
|
|
|
|
Journal &journal;
|
2019-03-05 18:35:35 +01:00
|
|
|
|
std::string prefix;
|
|
|
|
|
std::string mes;
|
|
|
|
|
SystemResources flash;
|
2019-01-09 17:21:14 +01:00
|
|
|
|
using _Tfunc = JournalRecord &(*)(JournalRecord &);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
|
explicit JournalRecord(Journal &jr, char rc = 'M')
|
2019-01-04 16:29:57 +01:00
|
|
|
|
: recChar(rc), ord(jr.getOrd()), journal(jr)
|
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
writePrefix(flash);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
}
|
2019-03-05 18:35:35 +01:00
|
|
|
|
virtual ~JournalRecord() = default;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
JournalRecord &operator<<(const IntSequence &s);
|
|
|
|
|
JournalRecord &
|
|
|
|
|
operator<<(_Tfunc f)
|
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
(*f)(*this);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
JournalRecord &
|
|
|
|
|
operator<<(char c)
|
|
|
|
|
{
|
|
|
|
|
mes += c;
|
|
|
|
|
return *this;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
}
|
|
|
|
|
JournalRecord &
|
2019-03-05 18:35:35 +01:00
|
|
|
|
operator<<(const std::string &s)
|
2019-01-04 16:29:57 +01:00
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
mes += s;
|
|
|
|
|
return *this;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
}
|
|
|
|
|
JournalRecord &
|
|
|
|
|
operator<<(int i)
|
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
mes += std::to_string(i);
|
|
|
|
|
return *this;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
}
|
|
|
|
|
JournalRecord &
|
|
|
|
|
operator<<(double d)
|
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
mes += std::to_string(d);
|
|
|
|
|
return *this;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
}
|
|
|
|
|
protected:
|
2019-03-05 18:35:35 +01:00
|
|
|
|
void writePrefix(const SystemResources &f);
|
2019-06-05 18:17:43 +02:00
|
|
|
|
/* Writes a floating point number as a field of exactly ‘width’ characters
|
2019-03-05 18:35:35 +01:00
|
|
|
|
large. Note that the width will not be respected if the integer part is
|
|
|
|
|
too large. */
|
|
|
|
|
static void writeFloatTabular(std::ostream &s, double d, int width);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
};
|
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
|
/*
|
2019-06-05 18:17:43 +02:00
|
|
|
|
Constructs a ‘pair’ of symmetric records with a RAII-like logic:
|
|
|
|
|
— when fed with ‘endrec’, print the opening record
|
|
|
|
|
— subsequent records will have depth increased by 1
|
|
|
|
|
— when deleted, prints the symmetric closing record, and decrease depth
|
2019-03-05 18:35:35 +01:00
|
|
|
|
*/
|
2019-01-04 16:29:57 +01:00
|
|
|
|
class JournalRecordPair : public JournalRecord
|
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
std::string prefix_end;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
public:
|
2019-03-05 18:35:35 +01:00
|
|
|
|
explicit JournalRecordPair(Journal &jr)
|
2019-01-04 16:29:57 +01:00
|
|
|
|
: JournalRecord(jr, 'S')
|
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
|
journal.incrementDepth();
|
2019-01-04 16:29:57 +01:00
|
|
|
|
}
|
2019-01-09 16:26:42 +01:00
|
|
|
|
~JournalRecordPair() override;
|
2019-01-04 16:29:57 +01:00
|
|
|
|
private:
|
2019-03-05 18:35:35 +01:00
|
|
|
|
void writePrefixForEnd(const SystemResources &f);
|
2019-01-04 16:29:57 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|