123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420 |
- /**
- * @file tests/multithreading/lifegame/graph_manager.cpp
- * @author The ARTIS Development Team
- * See the AUTHORS or Authors.txt file
- */
- /*
- * ARTIS - the multimodeling and simulation environment
- * This file is a part of the ARTIS environment
- *
- * Copyright (C) 2013-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 <http://www.gnu.org/licenses/>.
- */
- #ifndef TESTS_MULTITHREADING_LIFEGAME_GRAPH_MANAGER_HPP
- #define TESTS_MULTITHREADING_LIFEGAME_GRAPH_MANAGER_HPP
- #include <tests/multithreading/lifegame/models.hpp>
- #include <artis-star/kernel/pdevs/multithreading/Coordinator.hpp>
- #include <artis-star/kernel/pdevs/GraphManager.hpp>
- #include <artis-star/kernel/pdevs/Simulator.hpp>
- namespace artis {
- namespace tests {
- namespace multithreading {
- namespace lifegame {
- struct GridGraphManagerParameters
- {
- 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
- : public artis::pdevs::GraphManager<common::DoubleTime,
- CellParameters,
- GridGraphManagerParameters>
- {
- public:
- enum submodels
- {
- CELL
- };
- FlatGraphManager(common::Coordinator<common::DoubleTime> *coordinator,
- const CellParameters ¶meters,
- const GridGraphManagerParameters &graph_parameters)
- :
- artis::pdevs::GraphManager<common::DoubleTime, CellParameters, GridGraphManagerParameters>(
- coordinator, parameters, graph_parameters)
- {
- 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;
- ss << "C_" << i << "_" << j;
- auto cell = new Simulator(ss.str(), parameters);
- _cells.push_back(cell);
- add_children(CELL, cell);
- }
- }
- 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
- if (j - 1 >= 0) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[i * line_number + j - 1],
- Cell::IN});
- }
- // south
- if (j + 1 < (int) line_number) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[i * line_number + j + 1],
- Cell::IN});
- }
- // west
- if (i - 1 >= 0) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[(i - 1) * line_number
- + j], Cell::IN});
- }
- // east
- if (i + 1 < (int) column_number) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[(i + 1) * line_number
- + j], Cell::IN});
- }
- // north west
- if (j - 1 >= 0 and i - 1 >= 0) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[(i - 1) * line_number + j
- - 1], Cell::IN});
- }
- // south west
- if (j + 1 < (int) line_number and i - 1 >= 0) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[(i - 1) * line_number + j
- + 1], Cell::IN});
- }
- // north east
- if (j - 1 >= 0 and i + 1 < (int) column_number) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[(i + 1) * line_number + j
- - 1], Cell::IN});
- }
- // south east
- if (j + 1 < (int) line_number and i + 1 < (int) column_number) {
- out({_cells[index], Cell::OUT})
- >> in({_cells[(i + 1) * line_number + j
- + 1], Cell::IN});
- }
- }
- }
- }
- ~FlatGraphManager() override
- {
- std::for_each(_cells.begin(), _cells.end(),
- std::default_delete<Simulator>());
- }
- private:
- typedef pdevs::Simulator<common::DoubleTime, Cell, CellParameters> Simulator;
- typedef std::vector<Simulator *> Simulators;
- Simulators _cells;
- };
- class ParallelBuiltFlatGraphManager : public FlatGraphManager
- {
- public:
- ParallelBuiltFlatGraphManager(
- common::Coordinator<common::DoubleTime> *coordinator,
- const CellParameters ¶meters,
- 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 ¶meters,
- 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;
- };
- }
- }
- }
- } // namespace artis tests multithreading lifegame
- #endif
|