-
Notifications
You must be signed in to change notification settings - Fork 13
9. Running Simulations
Simulating DEVS (and Cell-DEVS) models is Cadmium is pretty straightforward.
We will illustrate it with the GPT
model.
However, the process is equivalent for any DEVS model built in Cadmium 2.
This is the simplest approach to simulate a DEVS model.
#include <cadmium/core/logger/csv.hpp> // To import a CSV logger (to store simulation results in CSV file)
#include <cadmium/core/simulation/root_coordinator.hpp> // To import the root coordinator
#include <limits>
#include "gpt.hpp"
int main() {
// model-related configuration parameters
int jobPeriod = 3;
int processingTime = 1;
double obsTime = 102.;
// We create the model and forward it to the root coordinator
// NOTE THAT WE NEED A POINTER TO THE MODEL!
auto model = std::make_shared<GPT>("gpt", jobPeriod, processingTime, obsTime);
auto rootCoordinator = cadmium::RootCoordinator(model);
// We can add a logger to the root coordinator
// In this example, we use a CSV logger that uses ; to separate columns.
// Simulation results will be stored in the log_gpt.csv file.
auto logger = std::make_shared<cadmium::CSVLogger>("log_gpt.csv", ";");
rootCoordinator.setLogger(logger);
// To start the simulation we 1) start, 2) simulate 3) stop.
rootCoordinator.start();
// in simulate method, we can select a maximum simulation time (in this case, infinity)
rootCoordinator.simulate(std::numeric_limits<double>::infinity());
rootCoordinator.stop();
return 0;
}
In most of the cases, we don't just want to simulate our model, but also store the simulation results somewhere.
To do so, we must attach a logger to the top coordinator.
In the next example, we will attach a CSV logger to our simulation.
Simulation results will be stored in the log_gpt.csv
file:
#include <cadmium/core/logger/csv.hpp> // To import a CSV logger (to store simulation results in CSV file)
#include <cadmium/core/simulation/root_coordinator.hpp>
#include <limits>
#include "gpt.hpp"
int main() {
int jobPeriod = 3;
int processingTime = 1;
double obsTime = 102.;
auto model = std::make_shared<GPT>("gpt", jobPeriod, processingTime, obsTime);
auto rootCoordinator = cadmium::RootCoordinator(model);
// We can add a logger to the root coordinator
// In this example, we use a CSV logger that uses ; to separate columns.
// Simulation results will be stored in the log_gpt.csv file.
auto logger = std::make_shared<cadmium::CSVLogger>("log_gpt.csv", ";");
rootCoordinator.setLogger(logger);
rootCoordinator.start();
rootCoordinator.simulate(std::numeric_limits<double>::infinity());
rootCoordinator.stop();
return 0;
}
Once the simulation is done, we can open the log_gpt.csv
file. We will find something like this:
time;model_id;model_name;port_name;data
0;1;transducer;;{0,0,0}
0;2;processor;;inf
0;3;generator;;0
0;1;transducer;;{0,1,0}
0;2;processor;;1
0;3;generator;outGenerated;{0,0,-1}
Columns are separated by semicolons (this is configurable).
The time
column represents the simulation time.
On the other hand, model_id
and model_name
clearly identifies which model generated the log trace.
The meaning of the next two fields depends on the trace.
The port_name
column contains an optional field. If the column is empty, then the value in the data
column represents the model's state.
On the other hand, if the port_name
column is not empty, then data
represents an output message, and port_name
univoquely identifies which port generated this message.
If you have all the dependencies for running parallel simulation, you can give it a shot as follows:
#include <cadmium/core/logger/csv.hpp>
#include <cadmium/core/simulation/parallel_root_coordinator.hpp> //<! Use parallel coordinator instead!
#include <limits>
#include "gpt.hpp"
using namespace cadmium::example::gpt;
int main() {
// We created the model exactly in the same fashion
int jobPeriod = 3;
int processingTime = 1;
double obsTime = 102.;
auto model = std::make_shared<GPT>("gpt", jobPeriod, processingTime, obsTime);
// However, now we create a parallel root coordinator
auto rootCoordinator = cadmium::ParallelRootCoordinator(model);
// We can add a new logger as with the sequential coordinator
auto logger = std::make_shared<cadmium::CSVLogger>("log_gpt.csv", ";");
rootCoordinator.setLogger(logger);
// We run the simulation using the same methods!
rootCoordinator.start();
rootCoordinator.simulate(std::numeric_limits<double>::infinity());
rootCoordinator.stop();
return 0;
}