Parcourir la source

Add test for pdevs/mpi

Eric Ramat il y a 9 ans
Parent
commit
d870b26403

+ 21 - 14
CMakeLists.txt

@@ -58,6 +58,7 @@ ENDIF (COMMAND CMAKE_POLICY)
 
 PKG_CHECK_MODULES(PARADEVS REQUIRED paradevs-1.0)
 PKG_CHECK_MODULES(LIBXML REQUIRED libxml-2.0)
+
 #
  # Test the libboost header and libboost-text library.
 #
@@ -70,21 +71,28 @@ SET(Boost_USE_STATIC_RUNTIME ON)
 IF (WIN32)
   SET(Boost_THREADAPI "win32")
 ENDIF (WIN32)
-SET(Boost_DETAILED_FAILURE_MSG FALSE)
-SET(Boost_DEBUG FALSE)
 
-FIND_PACKAGE(Boost COMPONENTS graph timer system)
-IF (NOT Boost_GRAPH_FOUND)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
+  ${CMAKE_BINARY_DIR})
+
+find_package(MPI REQUIRED)
+if (NOT MPI_CXX_FOUND)
+  message(ERROR " failed to found a C++ compiler with MPI support.")
+else()
+  message(STATUS " MPI support enabled")
+  include_directories(${MPI_CXX_INCLUDE_PATH})
+endif ()
+
+message(STATUS "checking for Boost headers and libraries")
+find_package(Boost 1.55 REQUIRED COMPONENTS graph mpi timer serialization
+  system)
+if (NOT Boost_FOUND)
   MESSAGE(FATAL_ERROR "The boost graph library is required")
-ENDIF (NOT Boost_GRAPH_FOUND)
-IF (Boost_MINOR_VERSION AND ${Boost_MINOR_VERSION} LESS "35")
-  SET(Boost_SYSTEM_LIBRARY "")
-ENDIF (Boost_MINOR_VERSION AND ${Boost_MINOR_VERSION} LESS "35")
-IF (Boost_MINOR_VERSION AND ${Boost_MINOR_VERSION} LESS "41")
-  SET(PARADEVS_HAVE_BOOST_SPIRIT2 0 CACHE INTERNAL "" FORCE)
-ELSE (Boost_MINOR_VERSION AND ${Boost_MINOR_VERSION} LESS "41")
-  SET(PARADEVS_HAVE_BOOST_SPIRIT2 1 CACHE INTERNAL "" FORCE)
-ENDIF (Boost_MINOR_VERSION AND ${Boost_MINOR_VERSION} LESS "41")
+else ()
+  message(STATUS " Boost found")
+  include_directories(${Boost_INCLUDE_DIRS})
+  link_directories(${Boost_LIBRARY_DIRS})
+endif ()
 
 #
  # Generate the config.h
@@ -93,7 +101,6 @@ ENDIF (Boost_MINOR_VERSION AND ${Boost_MINOR_VERSION} LESS "41")
 CHECK_INCLUDE_FILE_CXX(cxxabi.h PARADEVS_HAVE_GCC_ABI_DEMANGLE)
 CHECK_INCLUDE_FILE_CXX(execinfo.h PARADEVS_HAVE_EXECINFO)
 CHECK_INCLUDE_FILE_CXX(signal.h PARADEVS_HAVE_SIGNAL)
-INCLUDE_DIRECTORIES(${PARADEVS_BINARY_DIR})
 
 #
  # Browse the src subdirectory

+ 1 - 11
src/tests/CMakeLists.txt

@@ -1,18 +1,8 @@
-INCLUDE_DIRECTORIES(
-  ${PARADEVS_BINARY_DIR}/src
-  ${PARADEVS_SOURCE_DIR}/src
-  ${Boost_INCLUDE_DIRS}
-  ${GLIBMM_INCLUDE_DIRS}
-  ${LIBXML_INCLUDE_DIRS})
-
-LINK_DIRECTORIES(
-  ${GLIBMM_LIBRARY_DIRS}
-  ${LIBXML_LIBRARY_DIR})
-
 ADD_SUBDIRECTORY(boost_graph)
 ADD_SUBDIRECTORY(common)
 #ADD_SUBDIRECTORY(corsen)
 ADD_SUBDIRECTORY(dtss)
 ADD_SUBDIRECTORY(mixed)
+ADD_SUBDIRECTORY(mpi)
 ADD_SUBDIRECTORY(multithreading)
 ADD_SUBDIRECTORY(pdevs)

+ 26 - 0
src/tests/mpi/CMakeLists.txt

@@ -0,0 +1,26 @@
+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-tests graph_manager.hpp tests.cpp)
+
+#TARGET_LINK_LIBRARIES(pdevs-mpi-tests
+#  ${Boost_MPI_LIBRARY}
+#  ${Boost_SYSTEM_LIBRARY}
+#  ${Boost_TIMER_LIBRARY}
+#  ${MPI_CXX_LIBRARIES})
+
+ADD_EXECUTABLE(pdevs-mpi-main graph_manager.hpp main.cpp)
+
+TARGET_LINK_LIBRARIES(pdevs-mpi-main
+  ${Boost_SERIALIZATION_LIBRARY}
+  ${Boost_MPI_LIBRARY}
+  ${MPI_CXX_LIBRARIES})

+ 309 - 0
src/tests/mpi/graph_manager.hpp

@@ -0,0 +1,309 @@
+/**
+ * @file tests/mpi/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_GRAPH_MANAGER_HPP
+#define TESTS_PDEVS_MPI_GRAPH_MANAGER_HPP 1
+
+#include <tests/pdevs/models.hpp>
+#include <tests/pdevs/graph_manager.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>
+
+namespace paradevs { namespace tests { namespace mpi {
+
+class S1GraphManager :
+        public paradevs::pdevs::mpi::GraphManager < common::DoubleTime >
+{
+public:
+    S1GraphManager(common::Coordinator < common::DoubleTime >* coordinator,
+                   const paradevs::common::NoParameters& parameters) :
+        paradevs::pdevs::mpi::GraphManager < common::DoubleTime >(coordinator,
+                                                                  parameters),
+        a("a1", common::NoParameters()),
+        b("b1", common::NoParameters())
+    {
+        add_child(&a);
+        add_child(&b);
+
+        a.add_out_port("out");
+        b.add_in_port("in");
+        b.add_out_port("out");
+        coordinator->add_out_port("out");
+
+        add_link(&a, "out", &b, "in");
+        add_link(&b, "out", coordinator, "out");
+    }
+
+    void init()
+    { }
+
+    void start(common::DoubleTime::type /* t */)
+    { }
+
+    void transition(
+        const common::Models < common::DoubleTime >& /* receivers */,
+        common::DoubleTime::type /* t */)
+    { }
+
+    virtual ~S1GraphManager()
+    { }
+
+private:
+    paradevs::pdevs::Simulator < common::DoubleTime, pdevs::A  > a;
+    paradevs::pdevs::Simulator < common::DoubleTime, pdevs::B  > b;
+};
+
+class S2GraphManager :
+        public paradevs::pdevs::mpi::GraphManager < common::DoubleTime >
+{
+public:
+    S2GraphManager(common::Coordinator < common::DoubleTime >* coordinator,
+                   const paradevs::common::NoParameters& parameters) :
+        paradevs::pdevs::mpi::GraphManager < common::DoubleTime >(coordinator,
+                                                                  parameters),
+        a("a2", common::NoParameters()),
+        b("b2", common::NoParameters())
+    {
+        add_child(&a);
+        add_child(&b);
+
+        a.add_in_port("in");
+        a.add_out_port("out");
+        b.add_in_port("in");
+        coordinator->add_in_port("in");
+
+        add_link(&a, "out", &b, "in");
+        add_link(coordinator, "in", &a, "in");
+    }
+
+    void init()
+    { }
+
+    void start(common::DoubleTime::type /* t */)
+    { }
+
+    void transition(
+        const common::Models < common::DoubleTime >& /* receivers */,
+        common::DoubleTime::type /* t */)
+    { }
+
+    virtual ~S2GraphManager()
+    { }
+
+private:
+    paradevs::pdevs::Simulator < common::DoubleTime, pdevs::A  > a;
+    paradevs::pdevs::Simulator < common::DoubleTime, pdevs::B  > b;
+};
+
+struct RootGraphManagerParameters
+{
+    int S1_rank;
+    int S2_rank;
+};
+
+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),
+        S1("a", parameters.S1_rank, false),
+        S2("b", parameters.S2_rank, false)
+    {
+        add_child(&S1);
+        add_child(&S2);
+
+        add_link(&S1, "out", &S2, "in");
+    }
+
+    virtual ~RootGraphManager()
+    { }
+
+private:
+    paradevs::pdevs::mpi::ModelProxy < common::DoubleTime > S1;
+    paradevs::pdevs::mpi::ModelProxy < common::DoubleTime > S2;
+};
+
+// class S3GraphManager :
+//         public paradevs::pdevs::GraphManager < common::DoubleTime >
+// {
+// public:
+//     S3GraphManager(common::Coordinator < common::DoubleTime >* coordinator,
+//                    const paradevs::common::NoParameters& parameters) :
+//         paradevs::pdevs::GraphManager < common::DoubleTime >(coordinator,
+//                                                              parameters)
+//     {
+//         coordinator->add_out_port("out");
+//         for (unsigned int i = 0; i < 10; ++i) {
+//             std::ostringstream ss;
+//             simulator_type* s = new simulator_type(ss.str(),
+//                                                    common::NoParameters());
+
+//             ss << "a" << (i + 1);
+//             _simulators.push_back(s);
+//             add_child(s);
+//             s->add_out_port("out");
+//         }
+//     }
+
+//     void init()
+//     { }
+
+//     void start(common::DoubleTime::type /* t */)
+//     { }
+
+//     void transition(
+//         const common::Models < common::DoubleTime >& /* receivers */,
+//         common::DoubleTime::type /* t */)
+//     { }
+
+//     virtual ~S3GraphManager()
+//     {
+//         for (typename std::vector < simulator_type* >::const_iterator it =
+//                  _simulators.begin(); it != _simulators.end(); ++it) {
+//             delete *it;
+//         }
+//     }
+
+// private:
+//     typedef paradevs::pdevs::Simulator < common::DoubleTime,
+//                                          pdevs::A > simulator_type;
+
+//     std::vector < simulator_type* > _simulators;
+// };
+
+// class Root2GraphManager :
+//         public paradevs::pdevs::GraphManager < common::DoubleTime >
+// {
+// public:
+//     Root2GraphManager(
+//         common::Coordinator < common::DoubleTime >* coordinator,
+//         const paradevs::common::NoParameters& parameters) :
+//         paradevs::pdevs::GraphManager < common::DoubleTime >(
+//                                             coordinator, parameters),
+//         S1("S1", paradevs::common::NoParameters(),
+//            paradevs::common::NoParameters()),
+//         S2("S2", paradevs::common::NoParameters(),
+//            paradevs::common::NoParameters())
+//     {
+//         add_child(&S1);
+//         add_child(&S2);
+//     }
+
+//     void init()
+//     {
+//         S1.set_sender(
+//             dynamic_cast < paradevs::pdevs::mpi::Coordinator <
+//                 common::DoubleTime,
+//                 paradevs::tests::mpi::Root2GraphManager >*
+//             >(get_coordinator())->get_sender());
+//         S2.set_sender(
+//             dynamic_cast < paradevs::pdevs::mpi::Coordinator <
+//                 common::DoubleTime,
+//                 paradevs::tests::mpi::Root2GraphManager >*
+//             >(get_coordinator())->get_sender());
+//     }
+
+//     void start(common::DoubleTime::type t)
+//     {
+//         S1.get_sender().send(
+//             paradevs::pdevs::mpi::start_message <
+//                 common::DoubleTime >(t));
+//         S2.get_sender().send(
+//             paradevs::pdevs::mpi::start_message <
+//                 common::DoubleTime >(t));
+//     }
+
+//     void transition(const common::Models < common::DoubleTime >& receivers,
+//                     common::DoubleTime::type t)
+//     {
+//         if (std::find(receivers.begin(), receivers.end(),
+//                       &S1) != receivers.end()) {
+//             S1.get_sender().send(
+//                 paradevs::pdevs::mpi::transition_message <
+//                     common::DoubleTime >(t));
+//         }
+//         if (std::find(receivers.begin(), receivers.end(),
+//                       &S2) != receivers.end()) {
+//             S2.get_sender().send(
+//                 paradevs::pdevs::mpi::transition_message <
+//                     common::DoubleTime >(t));
+//         }
+//     }
+
+//     virtual ~Root2GraphManager()
+//     { }
+
+// private:
+//     paradevs::pdevs::mpi::Coordinator <
+//         common::DoubleTime,
+//         S3GraphManager > S1;
+//     paradevs::pdevs::mpi::Coordinator <
+//         common::DoubleTime,
+//         S3GraphManager > S2;
+// };
+
+// class Root3GraphManager :
+//         public paradevs::pdevs::GraphManager < common::DoubleTime >
+// {
+// public:
+//     Root3GraphManager(
+//         common::Coordinator < common::DoubleTime >* coordinator,
+//         const paradevs::common::NoParameters& parameters) :
+//         paradevs::pdevs::GraphManager < common::DoubleTime >(
+//                                             coordinator, parameters),
+//         S1("S1", paradevs::common::NoParameters(),
+//            paradevs::common::NoParameters()),
+//         S2("S2", paradevs::common::NoParameters(),
+//            paradevs::common::NoParameters())
+//     {
+//         add_child(&S1);
+//         add_child(&S2);
+//     }
+
+//     virtual ~Root3GraphManager()
+//     { }
+
+// private:
+//     paradevs::pdevs::Coordinator <
+//         common::DoubleTime,
+//         S3GraphManager > S1;
+//     paradevs::pdevs::Coordinator <
+//         common::DoubleTime,
+//         S3GraphManager > S2;
+// };
+
+} } } // namespace paradevs tests mpi
+
+#endif

+ 87 - 0
src/tests/mpi/main.cpp

@@ -0,0 +1,87 @@
+/**
+ * @file tests/mpi/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 <tests/mpi/graph_manager.hpp>
+
+#include <paradevs/common/RootCoordinator.hpp>
+#include <paradevs/kernel/pdevs/mpi/LogicalProcessor.hpp>
+
+#include <boost/mpi/environment.hpp>
+#include <boost/mpi/communicator.hpp>
+
+using namespace paradevs::tests::mpi;
+using namespace paradevs::common;
+using namespace boost::mpi;
+
+int main(int argc, char *argv[])
+{
+    environment env(argc, argv);
+    communicator world;
+
+    if (world.rank() == 0) {
+        paradevs::tests::mpi::RootGraphManagerParameters parameters;
+
+        parameters.S1_rank = 1;
+        parameters.S2_rank = 2;
+
+        paradevs::common::RootCoordinator <
+            DoubleTime,
+            paradevs::pdevs::Coordinator <
+                DoubleTime,
+                paradevs::tests::mpi::RootGraphManager,
+                paradevs::common::NoParameters,
+                paradevs::tests::mpi::RootGraphManagerParameters >
+            > rc(0, 10, "root", paradevs::common::NoParameters(), parameters);
+
+        rc.run();
+    } else {
+        if (world.rank() == 1) {
+            paradevs::pdevs::mpi::Coordinator <
+                DoubleTime,
+                paradevs::tests::mpi::S1GraphManager > model(
+                    "S1", paradevs::common::NoParameters(),
+                    paradevs::common::NoParameters());
+            paradevs::pdevs::mpi::LogicalProcessor <
+                DoubleTime > LP(&model, world.rank(), 0);
+
+            model.set_logical_processor(&LP);
+            LP.loop();
+        } else if (world.rank() == 2) {
+            paradevs::pdevs::mpi::Coordinator <
+                DoubleTime,
+                paradevs::tests::mpi::S2GraphManager > model(
+                    "S2", paradevs::common::NoParameters(),
+                    paradevs::common::NoParameters());
+            paradevs::pdevs::mpi::LogicalProcessor <
+                DoubleTime > LP(&model, world.rank(), 0);
+
+            model.set_logical_processor(&LP);
+            LP.loop();
+        }
+    }
+
+    return 0;
+}

+ 124 - 0
src/tests/mpi/tests.cpp

@@ -0,0 +1,124 @@
+/**
+ * @file tests/mpi/tests.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 <tests/mpi/graph_manager.hpp>
+#include <tests/pdevs/graph_manager.hpp>
+
+#include <paradevs/common/RootCoordinator.hpp>
+
+#include <chrono>
+
+#define CATCH_CONFIG_MAIN
+#include <tests/catch.hpp>
+
+using namespace paradevs::tests::pdevs;
+using namespace paradevs::tests::mpi;
+using namespace paradevs::common;
+using namespace std::chrono;
+
+TEST_CASE("pdevs/mpi/hierachical", "run")
+{
+    steady_clock::time_point t1 = steady_clock::now();
+
+    paradevs::common::RootCoordinator <
+        DoubleTime,
+        paradevs::pdevs::mpi::Coordinator <
+            DoubleTime,
+            paradevs::tests::mpi::RootGraphManager
+            >
+        > rc(0, 100, "root");
+
+    rc.run();
+
+    steady_clock::time_point t2 = steady_clock::now();
+
+    duration < double > time_span = duration_cast <
+        duration < double > >(t2 - t1);
+
+    std::cout << "mpi/dependant -> " << time_span.count()
+              << std::endl;
+}
+
+// TEST_CASE("pdevs/classic/hierachical", "run")
+// {
+//     steady_clock::time_point t1 = steady_clock::now();
+
+//     paradevs::common::RootCoordinator <
+//         DoubleTime, paradevs::pdevs::Coordinator <
+//             DoubleTime, paradevs::tests::pdevs::RootGraphManager >
+//         > rc(0, 100, "root", paradevs::common::NoParameters(),
+//              paradevs::common::NoParameters());
+
+//     rc.run();
+
+//     steady_clock::time_point t2 = steady_clock::now();
+
+//     duration < double > time_span = duration_cast <
+//         duration < double > >(t2 - t1);
+
+//     std::cout << "classic/dependant -> " << time_span.count() << std::endl;
+// }
+
+// TEST_CASE("pdevs/mpi/independant", "run")
+// {
+//     steady_clock::time_point t1 = steady_clock::now();
+
+//     paradevs::common::RootCoordinator <
+//         DoubleTime, paradevs::pdevs::mpi::Coordinator <
+//             DoubleTime, paradevs::tests::mpi::Root2GraphManager >
+//         > rc(0, 100, "root", paradevs::common::NoParameters(),
+//              paradevs::common::NoParameters());
+
+//     rc.run();
+
+//     steady_clock::time_point t2 = steady_clock::now();
+
+//     duration < double > time_span = duration_cast <
+//         duration < double > >(t2 - t1);
+
+//     std::cout << "mpi/independant -> " << time_span.count()
+//               << std::endl;
+// }
+
+// TEST_CASE("pdevs/classic/independant", "run")
+// {
+//     steady_clock::time_point t1 = steady_clock::now();
+
+//     paradevs::common::RootCoordinator <
+//         DoubleTime, paradevs::pdevs::Coordinator <
+//             DoubleTime, paradevs::tests::mpi::Root3GraphManager >
+//         > rc(0, 100, "root", paradevs::common::NoParameters(),
+//              paradevs::common::NoParameters());
+
+//     rc.run();
+
+//     steady_clock::time_point t2 = steady_clock::now();
+
+//     duration < double > time_span = duration_cast <
+//         duration < double > >(t2 - t1);
+
+//     std::cout << "classic/independant -> " << time_span.count() << std::endl;
+// }

+ 1 - 0
src/tests/pdevs/models.hpp

@@ -292,6 +292,7 @@ public:
                 common::START);
         common::Trace < common::DoubleTime >::trace().flush();
 #endif
+
         _phase = WAIT;
         return std::numeric_limits < double >::max();
     }