/** * @file utils/Trace.hpp * @author See the AUTHORS file */ /* * Copyright (C) 2012-2019 ULCO http://www.univ-littoral.fr * * This program 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. * * This program 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 this program. If not, see . */ #ifndef ARTIS_UTILS_TRACE #define ARTIS_UTILS_TRACE #include #include #include #include #include #include #include #include #include #include #if WIN32 #include #endif //fwd decl for friend classes in TraceElement namespace artis { namespace kernel { template class AbstractCoupledModel; template class AbstractAtomicModel; template class AbstractModel; template class Internals; template class Externals; } } namespace artis { namespace utils { enum TraceType { NONE = 0, CHECK = 1, CONSTRUCT, SUBMODEL_ADD, INTERNAL_DECL, EXTERNAL_DECL, INTERNAL_LINK, INIT, START, BEFORE_COMPUTE, COMPUTE, PUT, AFTER_COMPUTE, DESTRUCT, KERNEL }; static const std::vector TraceTypesStr = { "none", "check", "construct", "submodel_add", "internal_decl", "external_decl", "internal_link", "init", "start", "before_compute", "compute", "put", "after_compute", "destruct", "kernel"}; class KernelInfo { public: static std::map elt_dictionary; static std::vector elt_names; static unsigned int term(const std::string& v) { if (elt_dictionary.find(v) == elt_dictionary.end()) { elt_dictionary[v] = elt_names.size(); elt_names.push_back(v); } return elt_dictionary[v]; } static const std::string& term(unsigned int i) { return elt_names[i]; } KernelInfo() : _internal_var(false), _empty(true) { set_var(""); set_value(""); set_tgt_model(""); set_tgt_internal_var(""); } KernelInfo(const std::string& var, bool internal_var, const std::string& value) : _internal_var(internal_var), _empty(false) { set_var(var); set_value(value); set_tgt_model(""); set_tgt_internal_var(""); } KernelInfo(const std::string& var, const std::string& tgt_model, const std::string& tgt_internal_var) : _internal_var(true), _empty(false) { set_var(var); set_value(""); set_tgt_model(tgt_model); set_tgt_internal_var(tgt_internal_var); } KernelInfo(const std::string& var, bool internal_var) : _internal_var(internal_var), _empty(false) { set_var(var); set_value(""); set_tgt_model(""); set_tgt_internal_var(""); } KernelInfo(const std::string& tgt_model) : _internal_var(false), _empty(false) { set_var(""); set_value(""); set_tgt_model(tgt_model); set_tgt_internal_var(""); } void set_var(const std::string& v) { _var = KernelInfo::term(v); } void set_value(const std::string& v) { _value = KernelInfo::term(v); } void set_tgt_model(const std::string& v) { _tgt_model = KernelInfo::term(v); } void set_tgt_internal_var(const std::string& v) { _tgt_internal_var = KernelInfo::term(v); } const std::string& var() const { return KernelInfo::term(_var); } const std::string& value() const { return KernelInfo::term(_value); } const std::string& tgt_model() const { return KernelInfo::term(_tgt_model); } const std::string& tgt_internal_var() const { return KernelInfo::term(_tgt_internal_var); } unsigned int var_idx() const { return _var; } unsigned int tgt_internal_var_idx() const { return _tgt_internal_var; } unsigned int tgt_model_idx() const { return _tgt_model; } bool is_internal_var() const { return _internal_var; } bool empty() const { return _empty; } std::string to_string() const { std::ostringstream ss; if (not KernelInfo::term(_var).empty()) { ss << ":"; if (not _internal_var) ss << "*"; ss << KernelInfo::term(_var); } if (not KernelInfo::term(_value).empty()) { ss << "=" << KernelInfo::term(_value); } if (not KernelInfo::term(_tgt_model).empty()) { ss << " -> " << KernelInfo::term(_tgt_model); if (not KernelInfo::term(_tgt_internal_var).empty()) { ss << ":" << KernelInfo::term(_tgt_internal_var); } } return ss.str(); } private: unsigned int _var; unsigned int _value; unsigned int _tgt_model; unsigned int _tgt_internal_var; bool _internal_var; bool _empty; }; template class TraceElement { template friend class artis::kernel::AbstractCoupledModel; template friend class artis::kernel::AbstractAtomicModel; template friend class artis::kernel::AbstractModel; template friend class artis::kernel::Internals; template friend class artis::kernel::Externals; private: TraceElement(bool from_kernel, const std::string& model_name, typename Time::type time, TraceType type) : _time(time), _type(type), _from_kernel(from_kernel) { _model_name = KernelInfo::term(model_name); } public: TraceElement() :_time(Time::null), _type(NONE), _from_kernel(false) { } TraceElement(const std::string& model_name, typename Time::type time, TraceType type) : _time(time), _type(type), _from_kernel(false) { _model_name = KernelInfo::term(model_name); } virtual ~TraceElement() { } const std::string& get_comment() const { return _comment; } const std::string& get_model_name() const { return KernelInfo::term(_model_name); } unsigned int get_model_name_idx() const { return _model_name; } typename Time::type get_time() const { return _time; } TraceType get_type() const { return _type; } const KernelInfo& get_kernel_info() const { return _kernel_info; } void set_comment(const std::string& comment) { _comment = comment; } bool from_kernel() const { return _from_kernel; } void set_kernel_info(const KernelInfo& info) { _kernel_info = info; } std::string to_string(artis::utils::DateFormat date_format = artis::utils::DATE_FORMAT_EXTENDED) const { std::ostringstream ss; ss << (from_kernel() ? "KERNEL" : "TRACE "); if (get_time() != Time::null) { ss << "(" << utils::DateTime::toJulianDayFmt(get_time(), date_format) << ")"; } ss << ": "; ss << "<" + TraceTypesStr[get_type()] + ">"; ss << " " << get_model_name(); if (not get_kernel_info().empty()) { ss << get_kernel_info().to_string(); } if (not get_comment().empty()) { ss << " => " << get_comment(); } return ss.str(); } private: unsigned int _model_name; typename Time::type _time; TraceType _type; std::string _comment; KernelInfo _kernel_info; bool _from_kernel; }; template class TraceElements : public std::vector > { public: TraceElements() { } virtual ~TraceElements() { } TraceElements filter_model_name( const std::string& model_name) const { TraceElements