Program Listing for File LogFrame.h
↰ Return to documentation for file (include/flamegpu/simulation/LogFrame.h
)
#ifndef INCLUDE_FLAMEGPU_SIMULATION_LOGFRAME_H_
#define INCLUDE_FLAMEGPU_SIMULATION_LOGFRAME_H_
#include "AgentLoggingConfig.h"
#include <map>
#include <list>
#include <string>
#include <utility>
#include <vector>
#include "flamegpu/simulation/LoggingConfig.h"
#include "flamegpu/detail/Any.h"
#include "flamegpu/exception/FLAMEGPUException.h"
namespace flamegpu {
struct AgentLogFrame;
struct StepLogFrame;
struct ExitLogFrame;
struct LogFrame {
friend class CUDASimulation;
LogFrame();
LogFrame(const std::map<std::string, detail::Any> &_environment,
const std::map<util::StringPair, std::pair<std::map<LoggingConfig::NameReductionFn, detail::Any>, unsigned int>> &_agents,
unsigned int _step_count);
unsigned int getStepCount() const { return step_count; }
bool hasEnvironmentProperty(const std::string &property_name) const;
template<typename T>
T getEnvironmentProperty(const std::string &property_name) const;
template<typename T, unsigned int N>
std::array<T, N> getEnvironmentProperty(const std::string &property_name) const;
#ifdef SWIG
template<typename T>
std::vector<T> getEnvironmentPropertyArray(const std::string &property_name) const;
#endif
AgentLogFrame getAgent(const std::string &agent_name, const std::string &state_name = ModelData::DEFAULT_STATE) const;
const std::map<std::string, detail::Any> &getEnvironment() const { return environment; }
const std::map<util::StringPair, std::pair<std::map<LoggingConfig::NameReductionFn, detail::Any>, unsigned int>> &getAgents() const { return agents; }
private:
std::map<std::string, detail::Any> environment;
std::map<util::StringPair, std::pair<std::map<LoggingConfig::NameReductionFn, detail::Any>, unsigned int>> agents;
unsigned int step_count;
};
struct StepLogFrame : public LogFrame {
friend class CUDASimulation;
StepLogFrame();
StepLogFrame(const std::map<std::string, detail::Any>&& _environment,
const std::map<util::StringPair, std::pair<std::map<LoggingConfig::NameReductionFn, detail::Any>, unsigned int>>&& _agents,
unsigned int _step_count);
double getStepTime() const { return step_time; }
private:
double step_time;
};
struct ExitLogFrame : public LogFrame {
friend class CUDASimulation;
ExitLogFrame();
ExitLogFrame(const std::map<std::string, detail::Any>&& _environment,
const std::map<util::StringPair, std::pair<std::map<LoggingConfig::NameReductionFn, detail::Any>, unsigned int>>&& _agents,
unsigned int _step_count);
double getRTCTime() const { return rtc_time; }
double getInitTime() const { return init_time; }
double getExitTime() const { return exit_time; }
double getTotalTime() const { return total_time; }
private:
double rtc_time;
double init_time;
double exit_time;
double total_time;
};
struct RunLog {
struct PerformanceSpecs {
std::string device_name;
int device_cc_major;
int device_cc_minor;
int cuda_version;
bool seatbelts;
std::string flamegpu_version;
};
friend class CUDASimulation;
RunLog() { }
RunLog(const ExitLogFrame &_exit, const std::list<StepLogFrame> &_step)
: exit(_exit)
, step(_step) { }
const ExitLogFrame &getExitLog() const { return exit; }
const std::list<StepLogFrame> &getStepLog() const {return step; }
uint64_t getRandomSeed() const { return random_seed; }
unsigned int getStepLogFrequency() const { return step_log_frequency; }
PerformanceSpecs getPerformanceSpecs() const { return performance_specs; }
private:
ExitLogFrame exit;
std::list<StepLogFrame> step;
uint64_t random_seed = 0;
unsigned int step_log_frequency = 0;
PerformanceSpecs performance_specs;
};
struct AgentLogFrame {
explicit AgentLogFrame(const std::map<LoggingConfig::NameReductionFn, detail::Any> &data, unsigned int count);
unsigned int getCount() const;
template<typename T>
T getMin(const std::string &variable_name) const;
template<typename T>
T getMax(const std::string &variable_name) const;
template<typename T>
typename sum_input_t<T>::result_t getSum(const std::string &variable_name) const;
double getMean(const std::string &variable_name) const;
double getStandardDev(const std::string &variable_name) const;
private:
const std::map<LoggingConfig::NameReductionFn, detail::Any> &data;
const unsigned int count;
};
template<typename T>
T LogFrame::getEnvironmentProperty(const std::string &property_name) const {
const auto &it = environment.find(property_name);
if (it == environment.end()) {
THROW exception::InvalidEnvProperty("Environment property '%s' was not found in the log, "
"in LogFrame::getEnvironmentProperty()\n",
property_name.c_str());
}
if (it->second.type != std::type_index(typeid(T))) {
THROW exception::InvalidEnvPropertyType("Environment property '%s' has type %s, but requested type %s, "
"in LogFrame::getEnvironmentProperty()\n",
property_name.c_str(), it->second.type.name(), std::type_index(typeid(T)).name());
}
if (it->second.elements != 1) {
THROW exception::InvalidEnvPropertyType("Environment property '%s' is an array, use alternate function with array interface, "
"in LogFrame::getEnvironmentProperty()\n",
property_name.c_str(), it->second.type.name(), std::type_index(typeid(T)).name());
}
return *static_cast<T*>(it->second.ptr);
}
template<typename T, unsigned int N>
std::array<T, N> LogFrame::getEnvironmentProperty(const std::string &property_name) const {
const auto &it = environment.find(property_name);
if (it == environment.end()) {
THROW exception::InvalidEnvProperty("Environment property '%s' was not found in the log, "
"in LogFrame::getEnvironmentProperty()\n",
property_name.c_str());
}
if (it->second.type != std::type_index(typeid(T))) {
THROW exception::InvalidEnvPropertyType("Environment property '%s' has type %s, but requested type %s, "
"in LogFrame::getEnvironmentProperty()\n",
property_name.c_str(), it->second.type.name(), std::type_index(typeid(T)).name());
}
if (it->second.elements != N) {
THROW exception::InvalidEnvPropertyType("Environment property array '%s' has %u elements, but requested array with %u, "
"in LogFrame::getEnvironmentProperty()\n",
property_name.c_str(), it->second.elements, N);
}
std::array<T, N> rtn;
memcpy(rtn.data(), it->second.ptr, it->second.length);
return rtn;
}
#ifdef SWIG
template<typename T>
std::vector<T> LogFrame::getEnvironmentPropertyArray(const std::string& property_name) const {
const auto &it = environment.find(property_name);
if (it == environment.end()) {
THROW exception::InvalidEnvProperty("Environment property '%s' was not found in the log, "
"in LogFrame::getEnvironmentPropertyArray()\n",
property_name.c_str());
}
if (it->second.type != std::type_index(typeid(T))) {
THROW exception::InvalidEnvPropertyType("Environment property '%s' has type %s, but requested type %s, "
"in LogFrame::getEnvironmentPropertyArray()\n",
property_name.c_str(), it->second.type.name(), std::type_index(typeid(T)).name());
}
// Copy old data to return
std::vector<T> rtn(static_cast<size_t>(it->second.elements));
memcpy(rtn.data(), it->second.ptr, it->second.length);
return rtn;
}
#endif
template<typename T>
T AgentLogFrame::getMin(const std::string &variable_name) const {
const auto &it = data.find({variable_name, LoggingConfig::Min});
if (it == data.end()) {
THROW exception::InvalidAgentVar("Min of agent variable '%s' was not found in the log, "
"in AgentLogFrame::getMin()\n",
variable_name.c_str());
}
if (it->second.type != std::type_index(typeid(T))) {
THROW exception::InvalidVarType("Agent variable '%s' has type %s, but requested type %s, "
"in AgentLogFrame::getMin()\n",
variable_name.c_str(), it->second.type.name(), std::type_index(typeid(T)).name());
}
return *static_cast<T *>(it->second.ptr);
}
template<typename T>
T AgentLogFrame::getMax(const std::string &variable_name) const {
const auto &it = data.find({variable_name, LoggingConfig::Max});
if (it == data.end()) {
THROW exception::InvalidAgentVar("Max of agent variable '%s' was not found in the log, "
"in AgentLogFrame::getMax()\n",
variable_name.c_str());
}
if (it->second.type != std::type_index(typeid(T))) {
THROW exception::InvalidVarType("Agent variable '%s' has type %s, but requested type %s, "
"in AgentLogFrame::getMax()\n",
variable_name.c_str(), it->second.type.name(), std::type_index(typeid(T)).name());
}
return *static_cast<T *>(it->second.ptr);
}
template<typename T>
typename sum_input_t<T>::result_t AgentLogFrame::getSum(const std::string &variable_name) const {
const auto &it = data.find({variable_name, LoggingConfig::Sum});
if (it == data.end()) {
THROW exception::InvalidAgentVar("Sum of agent variable '%s' was not found in the log, "
"in AgentLogFrame::getSum()\n",
variable_name.c_str());
}
if (it->second.type != std::type_index(typeid(typename sum_input_t<T>::result_t))) {
THROW exception::InvalidVarType("Agent variable is not of type '%s', but requested type %s, "
"in AgentLogFrame::getSum()\n",
variable_name.c_str(), std::type_index(typeid(T)).name());
}
return *static_cast<typename sum_input_t<T>::result_t *>(it->second.ptr);
}
} // namespace flamegpu
#endif // INCLUDE_FLAMEGPU_SIMULATION_LOGFRAME_H_