Parcourir la source

New examples (mpi)

Eric RAMAT il y a 7 ans
Parent
commit
495d5ff5c6

+ 3 - 1
src/tests/mpi/CMakeLists.txt

@@ -26,4 +26,6 @@ TARGET_LINK_LIBRARIES(pdevs-mpi-main
   ${CMAKE_THREAD_LIBS_INIT}
   ${Boost_SERIALIZATION_LIBRARY}
   ${Boost_MPI_LIBRARY}
-  ${MPI_CXX_LIBRARIES})
+  ${MPI_CXX_LIBRARIES})
+
+ADD_SUBDIRECTORY(cluster)

+ 19 - 0
src/tests/mpi/cluster/CMakeLists.txt

@@ -0,0 +1,19 @@
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}/src
+  ${PARADEVS_INCLUDE_DIRS}
+  ${Boost_INCLUDE_DIRS}
+  ${GLIBMM_INCLUDE_DIRS}
+  ${LIBXML_INCLUDE_DIRS})
+
+LINK_DIRECTORIES(
+  ${Boost_LIBRARY_DIRS}
+  ${GLIBMM_LIBRARY_DIRS}
+  ${LIBXML_LIBRARY_DIR})
+
+ADD_EXECUTABLE(pdevs-mpi-cluster-main graph_manager.hpp models.hpp main.cpp)
+
+TARGET_LINK_LIBRARIES(pdevs-mpi-cluster-main
+  ${CMAKE_THREAD_LIBS_INIT}
+  ${Boost_SERIALIZATION_LIBRARY}
+  ${Boost_MPI_LIBRARY}
+  ${MPI_CXX_LIBRARIES})

+ 139 - 0
src/tests/mpi/cluster/graph_manager.hpp

@@ -0,0 +1,139 @@
+/**
+ * @file tests/mpi/cluster/graph_manager.cpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013-2015 ULCO http://www.univ-litoral.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_PDEVS_MPI_CLUSTER_GRAPH_MANAGER_HPP
+#define TESTS_PDEVS_MPI_CLUSTER_GRAPH_MANAGER_HPP 1
+
+#include <tests/pdevs/graph_manager.hpp>
+#include <tests/mpi/cluster/models.hpp>
+
+#include <paradevs/kernel/pdevs/mpi/Coordinator.hpp>
+#include <paradevs/kernel/pdevs/mpi/ModelProxy.hpp>
+#include <paradevs/kernel/pdevs/mpi/GraphManager.hpp>
+#include <paradevs/kernel/pdevs/Simulator.hpp>
+
+#include <sstream>
+
+namespace paradevs { namespace tests { namespace mpi { namespace cluster {
+
+class SubGraphManager :
+    public paradevs::pdevs::mpi::GraphManager < common::DoubleTime >
+{
+public:
+  SubGraphManager(common::Coordinator < common::DoubleTime >* coordinator,
+		  const paradevs::common::NoParameters& parameters) :
+    paradevs::pdevs::mpi::GraphManager < common::DoubleTime >(coordinator,
+							      parameters)
+  {
+    Simulator* m = new Simulator("m", paradevs::common::NoParameters());
+    
+    models.push_back(m);    
+    m->add_in_port("in");
+    m->add_out_port("out");
+
+    coordinator->add_in_port("in");
+    coordinator->add_out_port("out");
+    
+    add_link(coordinator, "in", m, "in");
+    add_link(m, "out", coordinator, "out");
+  }
+
+  void init()
+  { }
+  
+  void start(common::DoubleTime::type /* t */)
+  { }
+  
+  void transition(const common::Models < common::DoubleTime >& /* receivers */,
+		  common::DoubleTime::type /* t */)
+  { }
+
+  virtual ~SubGraphManager()
+  {
+    std::for_each(models.begin(), models.end(),
+		  std::default_delete < Simulator >());
+  }
+
+private:
+  typedef paradevs::pdevs::Simulator < common::DoubleTime,
+				       ThreeStateModel > Simulator;
+  typedef std::vector < Simulator* > Simulators;
+  
+  Simulators models;
+};
+
+struct RootGraphManagerParameters
+{
+    std::vector < int > ranks;
+};
+
+class RootGraphManager :
+        public paradevs::pdevs::GraphManager < common::DoubleTime,
+                                               RootGraphManagerParameters >
+{
+public:
+    RootGraphManager(
+        common::Coordinator < common::DoubleTime >* coordinator,
+        const RootGraphManagerParameters& parameters) :
+        paradevs::pdevs::GraphManager < common::DoubleTime,
+                                        RootGraphManagerParameters >(
+                                            coordinator, parameters)
+    {
+        for (std::vector < int >::const_iterator it = parameters.ranks.begin();
+             it != parameters.ranks.end(); ++it) {
+            std::stringstream ss;
+            ModelProxy* model = 0;
+
+            ss << "S" << *it;
+            model = new ModelProxy(ss.str(), *it, false);
+            models.push_back(model);
+            add_child(model);
+	    
+	    // connections (part)
+            model->add_out_port("out");
+            model->add_in_port("in");
+            // if (it != parameters.ranks.begin()) {
+            //     add_link(previous, "out", model, "in");
+            // }
+        }
+    }
+
+    virtual ~RootGraphManager()
+    {
+        std::for_each(models.begin(), models.end(),
+                      std::default_delete < ModelProxy >());
+    }
+
+private:
+    typedef paradevs::pdevs::mpi::ModelProxy < common::DoubleTime > ModelProxy;
+    typedef std::vector < ModelProxy* > ModelProxies;
+
+    ModelProxies models;
+};
+
+} } } } // namespace paradevs tests mpi cluster
+
+#endif

+ 103 - 0
src/tests/mpi/cluster/main.cpp

@@ -0,0 +1,103 @@
+/**
+ * @file tests/mpi/cluster/main.cpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013-2015 ULCO http://www.univ-litoral.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/>.
+ */
+
+#include <paradevs/common/RootCoordinator.hpp>
+
+#include <boost/mpi/environment.hpp>
+#include <boost/mpi/communicator.hpp>
+
+#include <paradevs/common/time/DoubleTime.hpp>
+#include <paradevs/kernel/pdevs/mpi/LogicalProcessor.hpp>
+#include <tests/mpi/cluster/graph_manager.hpp>
+
+#include <chrono>
+
+using namespace paradevs::tests::mpi::cluster;
+using namespace paradevs::common;
+using namespace boost::mpi;
+using namespace std::chrono;
+
+void example_simple(int argc, char *argv[])
+{
+    environment env(argc, argv);
+    communicator world;
+
+    std::cout << "START " << world.rank() << std::endl;
+    
+    if (world.rank() == 0) {
+        paradevs::tests::mpi::cluster::RootGraphManagerParameters parameters;
+
+        parameters.ranks.push_back(1);
+        parameters.ranks.push_back(2);
+        parameters.ranks.push_back(3);
+        parameters.ranks.push_back(4);
+        parameters.ranks.push_back(5);
+        parameters.ranks.push_back(6);
+        parameters.ranks.push_back(7);
+        parameters.ranks.push_back(8);
+
+        paradevs::common::RootCoordinator <
+            DoubleTime,
+            paradevs::pdevs::Coordinator <
+                DoubleTime,
+                paradevs::tests::mpi::cluster::RootGraphManager,
+                paradevs::common::NoParameters,
+                paradevs::tests::mpi::cluster::RootGraphManagerParameters >
+            > rc(0, 10, "root", paradevs::common::NoParameters(), parameters);
+
+        steady_clock::time_point t1 = steady_clock::now();
+
+        rc.run();
+
+        steady_clock::time_point t2 = steady_clock::now();
+
+        duration < double > time_span = duration_cast <
+            duration < double > >(t2 - t1);
+
+        std::cout << "time = " << time_span.count() << std::endl;
+
+    } else {
+        std::stringstream ss;
+
+        ss << "S" << world.rank();
+	paradevs::pdevs::mpi::Coordinator <
+	  DoubleTime,
+	  paradevs::tests::mpi::cluster::SubGraphManager >
+	model(ss.str(), paradevs::common::NoParameters(),
+	      paradevs::common::NoParameters());
+	paradevs::pdevs::mpi::LogicalProcessor <
+	  DoubleTime > LP(&model, world.rank(), 0);
+	
+	model.set_logical_processor(&LP);
+	LP.loop();
+    }
+}
+
+int main(int argc, char *argv[])
+{
+  example_simple(argc, argv);
+  return 0;
+}

+ 221 - 0
src/tests/mpi/cluster/models.hpp

@@ -0,0 +1,221 @@
+/**
+ * @file tests/mpi/cluster/models.hpp
+ * @author The PARADEVS Development Team
+ * See the AUTHORS or Authors.txt file
+ */
+
+/*
+ * PARADEVS - the multimodeling and simulation environment
+ * This file is a part of the PARADEVS environment
+ *
+ * Copyright (C) 2013-2015 ULCO http://www.univ-litoral.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_MPI_CLUSTER_MODELS_HPP
+#define TESTS_MPI_CLUSTER_MODELS_HPP 1
+
+#include <paradevs/common/time/DoubleTime.hpp>
+
+#include <paradevs/kernel/pdevs/Dynamics.hpp>
+
+namespace paradevs { namespace tests { namespace mpi { namespace cluster {
+
+class ThreeStateModel :
+        public paradevs::pdevs::Dynamics < common::DoubleTime >
+{
+public:
+    ThreeStateModel(const std::string& name,
+                    const common::NoParameters& parameters) :
+        paradevs::pdevs::Dynamics < common::DoubleTime >(name, parameters)
+    { }
+    virtual ~ThreeStateModel()
+    { }
+
+    void compute()
+    {
+        for (unsigned int i = 0; i < heights.size(); ++i) {
+            if (heights[i] != -1 and heights[i] < 10) {
+                heights[i] += speeds[i] * scales[i];
+            }
+        }
+    }
+
+    void display() const
+    {
+        for (std::vector < double >::const_iterator it = heights.begin();
+             it != heights.end(); ++it) {
+            std::cout << *it << " ";
+        }
+        std::cout << std::endl;
+    }
+
+    void display_full() const
+    {
+        unsigned int i = 1;
+
+        for (std::vector < double >::const_iterator it = heights.begin();
+             it != heights.end(); ++it, ++i) {
+            if (*it > 10) {
+                std::cout << "S" << i;
+            }
+        }
+        std::cout << std::endl;
+    }
+
+    bool full() const
+    {
+        unsigned int n = 0;
+
+        for (std::vector < double >::const_iterator it = heights.begin();
+             it != heights.end(); ++it) {
+            if (*it > 10) {
+                ++n;
+            }
+        }
+        return n > 0;
+    }
+
+    bool full_N() const
+    {
+        unsigned int n = 0;
+
+        for (std::vector < double >::const_iterator it = heights.begin();
+             it != heights.end(); ++it) {
+            if (*it == -1) {
+                ++n;
+            }
+        }
+        return n >= 2;
+    }
+
+    void mark_full(typename common::DoubleTime::type t)
+    {
+        for (std::vector < double >::iterator it = heights.begin();
+             it != heights.end(); ++it) {
+            if (*it > 10) {
+                *it = -1;
+                _last_time = t;
+            }
+        }
+    }
+
+    void raz()
+    {
+        for (std::vector < double >::iterator it = heights.begin();
+             it != heights.end(); ++it) {
+            if (*it == -1) {
+                *it = 0;
+            }
+        }
+    }
+
+    void dconf(typename common::DoubleTime::type t,
+               typename common::DoubleTime::type e,
+               const common::Bag < common::DoubleTime >& msgs)
+    {
+        dext(t, e, msgs);
+    }
+
+    void dext(typename common::DoubleTime::type t,
+              typename common::DoubleTime::type /* e */,
+              const common::Bag < common::DoubleTime >& msgs)
+    {
+        for (common::Bag < common::DoubleTime >::const_iterator
+                 it = msgs.begin(); it != msgs.end(); ++it) {
+            ++n;
+        }
+
+        // std::cout << get_name() << "|I|" << (t - _last_time) << " ";
+
+        if (sigma == 1) {
+            if (n > 3) {
+                ++index;
+                if (index == scales.size()) {
+                    index = 0;
+                }
+                sigma = std::numeric_limits < double >::max();
+                if (scales[index] == 1) {
+                    scales[index] = 2;
+                } else {
+                    scales[index] = 1;
+                }
+
+                std::cout << get_name() << "||INF ";
+
+                n = 0;
+            }
+        } else {
+            sigma = 1;
+            n = 0;
+        }
+    }
+
+    void dint(typename common::DoubleTime::type t)
+    {
+        mark_full(t);
+        if (full_N()) {
+            raz();
+        }
+        compute();
+    }
+
+    typename common::DoubleTime::type start(
+        typename common::DoubleTime::type t)
+    {
+        heights = { 0, 0, 0, 0, 0 };
+        speeds = { 0.21, 0.3, 0.7, 0.56, 0.14 };
+        scales = { 1, 1, 1, 1, 1 };
+        index = 0;
+        n = 0;
+        sigma = 1;
+        _last_time = t;
+        return 0;
+    }
+
+    typename common::DoubleTime::type ta(
+        typename common::DoubleTime::type /* t */) const
+    { return sigma; }
+
+    common::Bag < common::DoubleTime > lambda(
+        typename common::DoubleTime::type t) const
+    {
+        common::Bag < common::DoubleTime > msgs;
+
+        if (full()) {
+
+            std::cout << get_name() << "|O|" << (t - _last_time) << " ";
+            // display_full();
+
+            msgs.push_back(common::ExternalEvent < common::DoubleTime >(
+                               "out", 0));
+        }
+        return msgs;
+    }
+
+private:
+    std::vector < double > heights;
+    std::vector < double > speeds;
+    std::vector < double > scales;
+    unsigned int index;
+    unsigned int n;
+    typename common::DoubleTime::type sigma;
+
+    typename common::DoubleTime::type _last_time;
+};
+
+} } } } // namespace paradevs tests mpi cluster
+
+#endif