|
@@ -39,8 +39,14 @@ namespace artis {
|
|
namespace lifegame {
|
|
namespace lifegame {
|
|
|
|
|
|
struct GridGraphManagerParameters {
|
|
struct GridGraphManagerParameters {
|
|
- unsigned int column_number;
|
|
|
|
- unsigned int line_number;
|
|
|
|
|
|
+ unsigned int begin_column;
|
|
|
|
+ unsigned int end_column;
|
|
|
|
+ unsigned int begin_line;
|
|
|
|
+ unsigned int end_line;
|
|
|
|
+ unsigned int min_column;
|
|
|
|
+ unsigned int max_column;
|
|
|
|
+ unsigned int min_line;
|
|
|
|
+ unsigned int max_line;
|
|
};
|
|
};
|
|
|
|
|
|
class FlatGraphManager
|
|
class FlatGraphManager
|
|
@@ -57,61 +63,76 @@ namespace artis {
|
|
artis::pdevs::GraphManager<common::DoubleTime, CellParameters, GridGraphManagerParameters>(
|
|
artis::pdevs::GraphManager<common::DoubleTime, CellParameters, GridGraphManagerParameters>(
|
|
coordinator, parameters, graph_parameters)
|
|
coordinator, parameters, graph_parameters)
|
|
{
|
|
{
|
|
- for (unsigned int i = 0; i < graph_parameters.column_number; ++i) {
|
|
|
|
- for (unsigned int j = 0; j < graph_parameters.line_number; ++j) {
|
|
|
|
|
|
+ unsigned int column_number =
|
|
|
|
+ graph_parameters.end_column - graph_parameters.begin_column + 1;
|
|
|
|
+ unsigned int line_number =
|
|
|
|
+ graph_parameters.end_line - graph_parameters.begin_line + 1;
|
|
|
|
+
|
|
|
|
+ for (unsigned int i = graph_parameters.begin_column;
|
|
|
|
+ i <= graph_parameters.end_column; ++i) {
|
|
|
|
+ for (unsigned int j = graph_parameters.begin_line;
|
|
|
|
+ j <= graph_parameters.end_line; ++j) {
|
|
std::ostringstream ss;
|
|
std::ostringstream ss;
|
|
|
|
|
|
- ss << "C_" << (i + 1) << "_" << (j + 1);
|
|
|
|
|
|
+ ss << "C_" << i << "_" << j;
|
|
|
|
|
|
- Simulator* cell = new Simulator(ss.str(), parameters);
|
|
|
|
|
|
+ auto cell = new Simulator(ss.str(), parameters);
|
|
|
|
|
|
_cells.push_back(cell);
|
|
_cells.push_back(cell);
|
|
add_children(CELL, cell);
|
|
add_children(CELL, cell);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- for (int i = 0; i < (int)graph_parameters.column_number; ++i) {
|
|
|
|
- for (int j = 0; j < (int)graph_parameters.line_number; ++j) {
|
|
|
|
- int index = i * graph_parameters.line_number + j;
|
|
|
|
|
|
+ for (int i = 0; i < (int) column_number; ++i) {
|
|
|
|
+ for (int j = 0; j < (int) line_number; ++j) {
|
|
|
|
+ int index = i * (int) line_number + j;
|
|
|
|
|
|
// north
|
|
// north
|
|
if (j - 1 >= 0) {
|
|
if (j - 1 >= 0) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[i * graph_parameters.line_number + j - 1], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[i * line_number + j - 1],
|
|
|
|
+ Cell::IN});
|
|
}
|
|
}
|
|
// south
|
|
// south
|
|
- if (j + 1 < (int)graph_parameters.line_number) {
|
|
|
|
|
|
+ if (j + 1 < (int) line_number) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[i * graph_parameters.line_number + j + 1], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[i * line_number + j + 1],
|
|
|
|
+ Cell::IN});
|
|
}
|
|
}
|
|
// west
|
|
// west
|
|
if (i - 1 >= 0) {
|
|
if (i - 1 >= 0) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[(i - 1) * graph_parameters.line_number + j], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[(i - 1) * line_number
|
|
|
|
+ + j], Cell::IN});
|
|
}
|
|
}
|
|
// east
|
|
// east
|
|
- if (i + 1 < (int)graph_parameters.column_number) {
|
|
|
|
|
|
+ if (i + 1 < (int) column_number) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[(i + 1) * graph_parameters.line_number + j], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[(i + 1) * line_number
|
|
|
|
+ + j], Cell::IN});
|
|
}
|
|
}
|
|
// north west
|
|
// north west
|
|
if (j - 1 >= 0 and i - 1 >= 0) {
|
|
if (j - 1 >= 0 and i - 1 >= 0) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[(i - 1) * graph_parameters.line_number + j - 1], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[(i - 1) * line_number + j
|
|
|
|
+ - 1], Cell::IN});
|
|
}
|
|
}
|
|
// south west
|
|
// south west
|
|
- if (j + 1 < (int)graph_parameters.line_number and i - 1 >= 0) {
|
|
|
|
|
|
+ if (j + 1 < (int) line_number and i - 1 >= 0) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[(i - 1) * graph_parameters.line_number + j + 1], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[(i - 1) * line_number + j
|
|
|
|
+ + 1], Cell::IN});
|
|
}
|
|
}
|
|
// north east
|
|
// north east
|
|
- if (j - 1 >= 0 and i + 1 < (int)graph_parameters.column_number) {
|
|
|
|
|
|
+ if (j - 1 >= 0 and i + 1 < (int) column_number) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[(i + 1) * graph_parameters.line_number + j - 1], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[(i + 1) * line_number + j
|
|
|
|
+ - 1], Cell::IN});
|
|
}
|
|
}
|
|
// south east
|
|
// south east
|
|
- if (j + 1 < (int)graph_parameters.line_number and i + 1 < (int)graph_parameters.column_number) {
|
|
|
|
|
|
+ if (j + 1 < (int) line_number and i + 1 < (int) column_number) {
|
|
out({_cells[index], Cell::OUT})
|
|
out({_cells[index], Cell::OUT})
|
|
- >> in({_cells[(i + 1) * graph_parameters.line_number + j + 1], Cell::IN});
|
|
|
|
|
|
+ >> in({_cells[(i + 1) * line_number + j
|
|
|
|
+ + 1], Cell::IN});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -119,7 +140,8 @@ namespace artis {
|
|
|
|
|
|
~FlatGraphManager() override
|
|
~FlatGraphManager() override
|
|
{
|
|
{
|
|
- std::for_each(_cells.begin(), _cells.end(), std::default_delete<Simulator>());
|
|
|
|
|
|
+ std::for_each(_cells.begin(), _cells.end(),
|
|
|
|
+ std::default_delete<Simulator>());
|
|
}
|
|
}
|
|
|
|
|
|
private:
|
|
private:
|
|
@@ -129,6 +151,254 @@ namespace artis {
|
|
Simulators _cells;
|
|
Simulators _cells;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ class ParallelBuiltFlatGraphManager : public FlatGraphManager {
|
|
|
|
+ public:
|
|
|
|
+ ParallelBuiltFlatGraphManager(
|
|
|
|
+ common::Coordinator<common::DoubleTime>* coordinator,
|
|
|
|
+ const CellParameters& parameters,
|
|
|
|
+ const GridGraphManagerParameters& graph_parameters)
|
|
|
|
+ :
|
|
|
|
+ FlatGraphManager(coordinator, parameters, graph_parameters)
|
|
|
|
+ {
|
|
|
|
+ // inputs
|
|
|
|
+ unsigned int k = 0;
|
|
|
|
+
|
|
|
|
+ // top / bottom
|
|
|
|
+ {
|
|
|
|
+ int j_top = (int) graph_parameters.begin_line - 1;
|
|
|
|
+ int j_bottom = (int) graph_parameters.end_line + 1;
|
|
|
|
+
|
|
|
|
+ for (int i = (int) graph_parameters.begin_column - 1;
|
|
|
|
+ i <= (int) graph_parameters.end_column + 1; ++i) {
|
|
|
|
+ std::ostringstream ss_out;
|
|
|
|
+
|
|
|
|
+ ++k;
|
|
|
|
+ if (i >= (int) graph_parameters.min_column
|
|
|
|
+ and i <= (int) graph_parameters.max_column
|
|
|
|
+ and j_top >= (int) graph_parameters.min_line) {
|
|
|
|
+ ss_out << "in_" << i << "_" << j_top;
|
|
|
|
+ coordinator->add_in_port({k, ss_out.str()});
|
|
|
|
+ }
|
|
|
|
+ ++k;
|
|
|
|
+ if (i >= (int) graph_parameters.min_column
|
|
|
|
+ and i <= (int) graph_parameters.max_column
|
|
|
|
+ and j_bottom <= (int) graph_parameters.max_line) {
|
|
|
|
+ ss_out << "in_" << i << "_" << j_bottom;
|
|
|
|
+ coordinator->add_in_port({k, ss_out.str()});
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // left / right
|
|
|
|
+ {
|
|
|
|
+ int i_left = (int) graph_parameters.begin_column - 1;
|
|
|
|
+ int i_right = (int) graph_parameters.end_column + 1;
|
|
|
|
+
|
|
|
|
+ for (int j = (int) graph_parameters.begin_line;
|
|
|
|
+ j <= (int) graph_parameters.end_line; ++j) {
|
|
|
|
+ std::ostringstream ss_out;
|
|
|
|
+
|
|
|
|
+ ++k;
|
|
|
|
+ if (j >= (int) graph_parameters.min_line
|
|
|
|
+ and j <= (int) graph_parameters.max_line
|
|
|
|
+ and i_left >= (int) graph_parameters.min_column) {
|
|
|
|
+ ss_out << "out_" << i_left << "_" << j;
|
|
|
|
+ coordinator->add_in_port({k, ss_out.str()});
|
|
|
|
+ }
|
|
|
|
+ ++k;
|
|
|
|
+ if (j >= (int) graph_parameters.min_line
|
|
|
|
+ and j <= (int) graph_parameters.max_line
|
|
|
|
+ and i_right >= (int) graph_parameters.max_column) {
|
|
|
|
+ ss_out << "out_" << i_right << "_" << j;
|
|
|
|
+ coordinator->add_in_port({k, ss_out.str()});
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // outputs
|
|
|
|
+ k = 0;
|
|
|
|
+
|
|
|
|
+ // top / bottom
|
|
|
|
+ {
|
|
|
|
+ int j_top = (int) graph_parameters.begin_line;
|
|
|
|
+ int j_bottom = (int) graph_parameters.end_line;
|
|
|
|
+
|
|
|
|
+ for (int i = (int) graph_parameters.begin_column;
|
|
|
|
+ i <= (int) graph_parameters.end_column; ++i) {
|
|
|
|
+ std::ostringstream ss_out;
|
|
|
|
+
|
|
|
|
+ ++k;
|
|
|
|
+ ss_out << "out_" << i << "_" << j_top;
|
|
|
|
+ coordinator->add_out_port({k, ss_out.str()});
|
|
|
|
+ ++k;
|
|
|
|
+ ss_out << "out_" << i << "_" << j_bottom;
|
|
|
|
+ coordinator->add_out_port({k, ss_out.str()});
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // left / right
|
|
|
|
+ {
|
|
|
|
+ int i_left = (int) graph_parameters.begin_column;
|
|
|
|
+ int i_right = (int) graph_parameters.end_column;
|
|
|
|
+
|
|
|
|
+ for (int j = (int) graph_parameters.begin_line + 1;
|
|
|
|
+ j <= (int) graph_parameters.end_line - 1; ++j) {
|
|
|
|
+ std::ostringstream ss_out;
|
|
|
|
+
|
|
|
|
+ ++k;
|
|
|
|
+ ss_out << "out_" << i_left << "_" << j;
|
|
|
|
+ coordinator->add_out_port({k, ss_out.str()});
|
|
|
|
+ ++k;
|
|
|
|
+ ss_out << "out_" << i_right << "_" << j;
|
|
|
|
+ coordinator->add_out_port({k, ss_out.str()});
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // for (Edges::const_iterator it = parameters._output_edges.begin();
|
|
|
|
+// it != parameters._output_edges.end(); ++it) {
|
|
|
|
+// std::ostringstream ss_out;
|
|
|
|
+//
|
|
|
|
+// ss_out << "out_" << it->first;
|
|
|
|
+// if (not coordinator->exist_out_port(ss_out.str())) {
|
|
|
|
+// coordinator->add_out_port(ss_out.str());
|
|
|
|
+// }
|
|
|
|
+// if (not ParallelBuiltFlatGraphManager::exist_link(
|
|
|
|
+// ParallelBuiltFlatGraphManager::_simulators[it->first],
|
|
|
|
+// "out", coordinator, ss_out.str())) {
|
|
|
|
+// ParallelBuiltFlatGraphManager::add_link(
|
|
|
|
+// ParallelBuiltFlatGraphManager::_simulators[it->first],
|
|
|
|
+// "out", coordinator, ss_out.str());
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void init() { }
|
|
|
|
+
|
|
|
|
+ void start(common::DoubleTime::type /* t */) { }
|
|
|
|
+
|
|
|
|
+ void transition(
|
|
|
|
+ const common::Models<common::DoubleTime>& /* receivers */,
|
|
|
|
+ common::DoubleTime::type /* t */) { }
|
|
|
|
+
|
|
|
|
+ ~ParallelBuiltFlatGraphManager() override = default;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ class ParallelHierarchicalGraphManager :
|
|
|
|
+ public artis::pdevs::GraphManager<common::DoubleTime, CellParameters, GridGraphManagerParameters> {
|
|
|
|
+ public:
|
|
|
|
+ enum submodels {
|
|
|
|
+ S1_1 = 0, S1_2, S2_1, S2_2
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ ParallelHierarchicalGraphManager(
|
|
|
|
+ common::Coordinator<common::DoubleTime>* coordinator,
|
|
|
|
+ const CellParameters& parameters,
|
|
|
|
+ const GridGraphManagerParameters& graph_parameters)
|
|
|
|
+ :
|
|
|
|
+ artis::pdevs::GraphManager<common::DoubleTime, CellParameters,
|
|
|
|
+ GridGraphManagerParameters>(
|
|
|
|
+ coordinator, parameters, graph_parameters)
|
|
|
|
+ {
|
|
|
|
+ // build coordinators (graphs)
|
|
|
|
+ for (unsigned int i = 0; i < 2; ++i) {
|
|
|
|
+ for (unsigned int j = 0; j < 2; ++j) {
|
|
|
|
+ ParallelCoordinator* sub_coordinator = nullptr;
|
|
|
|
+ std::ostringstream ss;
|
|
|
|
+
|
|
|
|
+ ss << "S_" << (i + 1) << "_" << (j + 1);
|
|
|
|
+ sub_coordinator = new ParallelCoordinator(ss.str(),
|
|
|
|
+ parameters,
|
|
|
|
+ {i * 5 + 1, (i + 1) * 5, j * 5 + 1, (j + 1) * 5,
|
|
|
|
+ 1, 10, 1, 10});
|
|
|
|
+ _coordinators.push_back(sub_coordinator);
|
|
|
|
+ add_child(i, sub_coordinator);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // builds internal connections (edges)
|
|
|
|
+// for (Connections::const_iterator it = parent_connections.begin();
|
|
|
|
+// it != parent_connections.end(); ++it) {
|
|
|
|
+// const Connection& connection = *it;
|
|
|
|
+// std::ostringstream ss_out;
|
|
|
|
+// std::ostringstream ss_in;
|
|
|
|
+//
|
|
|
|
+// ss_out << "out_" << connection.first.second;
|
|
|
|
+// ss_in << "in_" << connection.first.second;
|
|
|
|
+//
|
|
|
|
+// if (not exist_link(
|
|
|
|
+// _coordinators[connection.first.first - 1],
|
|
|
|
+// ss_out.str(),
|
|
|
|
+// _coordinators[connection.second.first - 1],
|
|
|
|
+// ss_in.str())) {
|
|
|
|
+// add_link(
|
|
|
|
+// _coordinators[connection.first.first - 1],
|
|
|
|
+// ss_out.str(),
|
|
|
|
+// _coordinators[connection.second.first - 1],
|
|
|
|
+// ss_in.str());
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ~ParallelHierarchicalGraphManager() override
|
|
|
|
+ {
|
|
|
|
+ for (typename Coordinators::const_iterator it = _coordinators.begin();
|
|
|
|
+ it != _coordinators.end(); ++it) {
|
|
|
|
+ delete *it;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void init()
|
|
|
|
+ {
|
|
|
|
+ std::for_each(_coordinators.begin(), _coordinators.end(),
|
|
|
|
+ [this](ParallelCoordinator* coordinator) {
|
|
|
|
+ coordinator->set_sender(
|
|
|
|
+ (dynamic_cast< artis::pdevs::multithreading::Coordinator<
|
|
|
|
+ artis::common::DoubleTime,
|
|
|
|
+ ParallelHierarchicalGraphManager,
|
|
|
|
+ CellParameters,
|
|
|
|
+ GridGraphManagerParameters>*>(this->coordinator()))->get_sender());
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void start(common::DoubleTime::type t)
|
|
|
|
+ {
|
|
|
|
+ std::for_each(_coordinators.begin(), _coordinators.end(),
|
|
|
|
+ [t](ParallelCoordinator* coordinator) {
|
|
|
|
+ coordinator->get_sender().send(
|
|
|
|
+ artis::pdevs::multithreading::start_message<
|
|
|
|
+ artis::common::DoubleTime>(t));
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void transition(const common::Models<common::DoubleTime>& receivers,
|
|
|
|
+ artis::common::DoubleTime::type t)
|
|
|
|
+ {
|
|
|
|
+ std::for_each(receivers.begin(), receivers.end(),
|
|
|
|
+ [this, t](const common::Model<common::DoubleTime>* model) {
|
|
|
|
+ if (not model->is_atomic()) {
|
|
|
|
+ typename Coordinators::const_iterator itc =
|
|
|
|
+ std::find(_coordinators.begin(),
|
|
|
|
+ _coordinators.end(), model);
|
|
|
|
+
|
|
|
|
+ (*itc)->get_sender().send(
|
|
|
|
+ artis::pdevs::multithreading::transition_message<
|
|
|
|
+ artis::common::DoubleTime>(t));
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private:
|
|
|
|
+ typedef artis::pdevs::multithreading::Coordinator<
|
|
|
|
+ common::DoubleTime,
|
|
|
|
+ ParallelBuiltFlatGraphManager,
|
|
|
|
+ CellParameters,
|
|
|
|
+ GridGraphManagerParameters
|
|
|
|
+ > ParallelCoordinator;
|
|
|
|
+ typedef std::vector<ParallelCoordinator*> Coordinators;
|
|
|
|
+
|
|
|
|
+ Coordinators _coordinators;
|
|
|
|
+ };
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|