Skip to content

Commit

Permalink
Refactored StateReader interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
Robadob committed Sep 4, 2023
1 parent cc6e35e commit 3ca63d6
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 328 deletions.
38 changes: 6 additions & 32 deletions include/flamegpu/io/JSONStateReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@

#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "flamegpu/io/StateReader.h"
#include "flamegpu/model/ModelDescription.h"
#include "flamegpu/util/StringPair.h"

namespace flamegpu {
namespace io {
Expand All @@ -20,33 +15,12 @@ namespace io {
class JSONStateReader : public StateReader {
public:
/**
* Constructs a reader capable of reading model state from JSON files
* Environment properties will be read into the Simulation instance pointed to by 'sim_instance_id'
* Agent data will be read into 'model_state'
* @param model_name Name from the model description hierarchy of the model to be loaded
* @param env_desc Environment description for validating property data on load
* @param env_init Dictionary of loaded values map:<name, value>
* @param macro_env_desc Macro environment description for validating property data on load
* @param macro_env_init Dictionary of loaded values map:<name, value>
* @param model_state Map of AgentVector to load the agent data into per agent, key should be agent name
* @param input_file Filename of the input file (This will be used to determine which reader to return)
* @param sim_instance Instance of the Simulation object (This is used for setting/getting config)
*/
JSONStateReader(
const std::string &model_name,
const std::unordered_map<std::string, EnvironmentData::PropData> &env_desc,
std::unordered_map<std::string, detail::Any> &env_init,
const std::unordered_map<std::string, EnvironmentData::MacroPropData> &macro_env_desc,
std::unordered_map<std::string, std::vector<char>> &macro_env_init,
util::StringPairUnorderedMap<std::shared_ptr<AgentVector>> &model_state,
const std::string &input_file,
Simulation *sim_instance);
/**
* Actual performs the XML parsing to load the model state
* @return Always 0
* @throws exception::RapidJSONError If parsing of the input file fails
*/
int parse() override;
* Loads the specified XML file to an internal data-structure
* @param input_file Path to file to be read
* @param model Model description to ensure file loaded is suitable
* @param verbosity Verbosity level to use during load
*/
void parse(const std::string &input_file, const std::shared_ptr<const ModelData> &model, Verbosity verbosity) override;
};
} // namespace io
} // namespace flamegpu
Expand Down
91 changes: 46 additions & 45 deletions include/flamegpu/io/StateReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <any>

#include "flamegpu/util/StringPair.h"
#include "flamegpu/model/EnvironmentData.h"
#include "flamegpu/simulation/Simulation.h"
#include "flamegpu/simulation/CUDASimulation.h"

namespace flamegpu {

Expand All @@ -24,60 +24,61 @@ namespace io {
*/
class StateReader {
public:
/**
* Constructs a reader capable of reading model state from a specific format (this class is abstract)
* Environment properties will be read into the Simulation instance pointed to by 'sim_instance_id'
* Agent data will be read into 'model_state'
* @param _model_name Name from the model description hierarchy of the model to be loaded
* @param _env_desc Environment description for validating property data on load
* @param _env_init Dictionary of loaded values map:<name, value>
* @param _macro_env_desc Macro environment description for validating property data on load
* @param _macro_env_init Dictionary of loaded values map:<name, value>
* @param _model_state Map of AgentVector to load the agent data into per agent, key should be agent name
* @param input Filename of the input file (This will be used to determine which reader to return)
* @param _sim_instance Instance of the simulation (for configuration data IO)
*/
StateReader(
const std::string& _model_name,
const std::unordered_map<std::string, EnvironmentData::PropData>& _env_desc,
std::unordered_map<std::string, detail::Any>& _env_init,
const std::unordered_map<std::string, EnvironmentData::MacroPropData>& _macro_env_desc,
std::unordered_map<std::string, std::vector<char>>& _macro_env_init,
util::StringPairUnorderedMap<std::shared_ptr<AgentVector>>& _model_state,
const std::string& input,
Simulation* _sim_instance)
: model_state(_model_state)
, inputFile(input)
, model_name(_model_name)
, env_desc(_env_desc)
, env_init(_env_init)
, macro_env_desc(_macro_env_desc)
, macro_env_init(_macro_env_init)
, sim_instance(_sim_instance) {}
/**
* Virtual destructor for correct inheritance behaviour
*/
virtual ~StateReader() {}

/**
* Loads the file to an internal data-structure
* @param input_file Path to file to be read
* @param model Model description to ensure file loaded is suitable
* @param verbosity Verbosity level to use during load
*/
virtual void parse(const std::string &input_file, const std::shared_ptr<const ModelData> &model, Verbosity verbosity) = 0;

// -----------------------------------------------------------------------
// The interface
// The Easy Interface
// -----------------------------------------------------------------------
/**
* Actually perform the file load
* @return Returns a return code
* @todo: This should probably be the same return code between subclasses, and seems redundant with our exceptions as should never return fail.
* Grab the full simulation state from the input file
* @note CUDASimulation Config is not included and should be requested separately
*/
virtual int parse() = 0;
void getFullModelState(
Simulation::Config &s_cfg,
std::unordered_map<std::string, detail::Any> &environment_init,
std::unordered_map<std::string, std::vector<char>> &macro_environment_init,
util::StringPairUnorderedMap<std::shared_ptr<AgentVector>> &agents_init);

// -----------------------------------------------------------------------
// The Advanced Interface
// -----------------------------------------------------------------------
/**
* Overwrite the provided simulation config with the one loaded from file
* @param cfg The config struct to be overwritten
* @throws If the parsed file did not contain a simulation config or a file has not been parsed
*/
void getSimulationConfig(Simulation::Config &cfg);
/**
* Overwrite the provided CUDA config with the one loaded from file
* @param cfg The config struct to be overwritten
* @throws If the parsed file did not contain a CUDA config or a file has not been parsed
*/
void getCUDAConfig(CUDASimulation::Config &cfg);
void getEnvironment(std::unordered_map<std::string, detail::Any> &environment_init);
void getMacroEnvironment(std::unordered_map<std::string, std::vector<char>> &macro_environment_init);
void getAgents(util::StringPairUnorderedMap<std::shared_ptr<AgentVector>> &agents_init);

protected:
util::StringPairUnorderedMap<std::shared_ptr<AgentVector>> &model_state;
std::string inputFile;
const std::string model_name;
const std::unordered_map<std::string, EnvironmentData::PropData> &env_desc;
std::unordered_map<std::string, detail::Any>& env_init;
const std::unordered_map<std::string, EnvironmentData::MacroPropData> &macro_env_desc;
std::unordered_map<std::string, std::vector<char>>& macro_env_init;
Simulation *sim_instance;
std::string input_filepath;

void resetCache();

std::unordered_map<std::string, std::any> simulation_config;
std::unordered_map<std::string, std::any> cuda_config;
std::unordered_map<std::string, detail::Any> env_init;
std::unordered_map<std::string, std::vector<char>> macro_env_init;
util::StringPairUnorderedMap<std::shared_ptr<AgentVector>> agents_map;
};
} // namespace io
} // namespace flamegpu
Expand Down
22 changes: 3 additions & 19 deletions include/flamegpu/io/StateReaderFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,17 @@ class StateReaderFactory {
public:
/**
* Returns a reader capable of reading 'input'
* Environment properties will be read into the Simulation instance pointed to by 'sim_instance_id'
* Agent data will be read into 'model_state'
* @param model_name Name from the model description hierarchy of the model to be loaded
* @param env_desc Environment description for validating property data on load
* @param env_init Dictionary of loaded values map:<name, value>
* @param macro_env_desc Macro environment description for validating property data on load
* @param macro_env_init Dictionary of loaded values map:<name, value>
* @param model_state Map of AgentVector to load the agent data into per agent, key should be agent name
* @param input Filename of the input file (This will be used to determine which reader to return)
* @param sim_instance Instance of the Simulation object (This is used for setting/getting config)
* @throws exception::UnsupportedFileType If the file extension does not match an appropriate reader
*/
static StateReader* createReader(
const std::string& model_name,
const std::unordered_map<std::string, EnvironmentData::PropData>& env_desc,
std::unordered_map<std::string, detail::Any>& env_init,
const std::unordered_map<std::string, EnvironmentData::MacroPropData>& macro_env_desc,
std::unordered_map<std::string, std::vector<char>>& macro_env_init,
util::StringPairUnorderedMap<std::shared_ptr<AgentVector>>& model_state,
const std::string& input,
Simulation* sim_instance) {
const std::string& input) {
const std::string extension = std::filesystem::path(input).extension().string();

if (extension == ".xml") {
return new XMLStateReader(model_name, env_desc, env_init, macro_env_desc, macro_env_init, model_state, input, sim_instance);
return new XMLStateReader();
} else if (extension == ".json") {
return new JSONStateReader(model_name, env_desc, env_init, macro_env_desc, macro_env_init, model_state, input, sim_instance);
return new JSONStateReader();
}
THROW exception::UnsupportedFileType("File '%s' is not a type which can be read "
"by StateReaderFactory::createReader().",
Expand Down
38 changes: 6 additions & 32 deletions include/flamegpu/io/XMLStateReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@

#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "flamegpu/io/StateReader.h"
#include "flamegpu/model/ModelDescription.h"
#include "flamegpu/util/StringPair.h"

namespace flamegpu {
namespace io {
Expand All @@ -19,40 +14,19 @@ namespace io {
class XMLStateReader : public StateReader {
public:
/**
* Constructs a reader capable of reading model state from XML files
* Environment properties will be read into the Simulation instance pointed to by 'sim_instance_id'
* Agent data will be read into 'model_state'
* @param model_name Name from the model description hierarchy of the model to be loaded
* @param env_desc Environment description for validating property data on load
* @param env_init Dictionary of loaded values map:<{name, index}, value>
* @param macro_env_desc Macro environment description for validating property data on load
* @param macro_env_init Dictionary of loaded values map:<name, value>
* @param model_state Map of AgentVector to load the agent data into per agent, key should be agent name
* @param input_file Filename of the input file (This will be used to determine which reader to return)
* @param sim_instance Instance of the Simulation object (This is used for setting/getting config)
* Loads the specified XML file to an internal data-structure
* @param input_file Path to file to be read
* @param model Model description to ensure file loaded is suitable
* @param verbosity Verbosity level to use during load
*/
XMLStateReader(
const std::string &model_name,
const std::unordered_map<std::string, EnvironmentData::PropData> &env_desc,
std::unordered_map<std::string, detail::Any> &env_init,
const std::unordered_map<std::string, EnvironmentData::MacroPropData> &macro_env_desc,
std::unordered_map<std::string, std::vector<char>> &macro_env_init,
util::StringPairUnorderedMap<std::shared_ptr<AgentVector>> &model_state,
const std::string &input_file,
Simulation *sim_instance);
/**
* Actual performs the XML parsing to load the model state
* @return Always tinyxml2::XML_SUCCESS
* @throws exception::TinyXMLError If parsing of the input file fails
*/
int parse() override;
void parse(const std::string &input_file, const std::shared_ptr<const ModelData> &model, Verbosity verbosity) override;

private:
/**
* Flamegpu1 xml input files are allowed to omit state
* This function extracts the initial state for the named agent from model_state;
*/
std::string getInitialState(const std::string& agent_name) const;
static std::string getInitialState(const std::shared_ptr<const ModelData> &model, const std::string& agent_name);
};
} // namespace io
} // namespace flamegpu
Expand Down
2 changes: 2 additions & 0 deletions include/flamegpu/model/ModelDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class ModelDescription {
friend class RunPlanVector;
friend class RunPlan;
friend class LoggingConfig;
friend class XMLStateReader;
friend class JSONStateReader;
public:
/**
* Constructor
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ SET(SRC_FLAMEGPU
${FLAMEGPU_ROOT}/src/flamegpu/runtime/random/HostRandom.cu
${FLAMEGPU_ROOT}/src/flamegpu/io/JSONStateReader.cu
${FLAMEGPU_ROOT}/src/flamegpu/io/JSONStateWriter.cu
${FLAMEGPU_ROOT}/src/flamegpu/io/StateReader.cu
${FLAMEGPU_ROOT}/src/flamegpu/io/XMLStateReader.cu
${FLAMEGPU_ROOT}/src/flamegpu/io/XMLStateWriter.cu
${FLAMEGPU_ROOT}/src/flamegpu/io/XMLLogger.cu
Expand Down
Loading

0 comments on commit 3ca63d6

Please sign in to comment.