From 8c0e7191f5a9c33da35309cf1c20214230043496 Mon Sep 17 00:00:00 2001
From: "f.mack" <mack.fabi@t-online.de>
Date: Thu, 25 Aug 2016 14:24:12 +0200
Subject: [PATCH] parallelized pre-simulation ff calculation

---
 Simulation.cpp                 |   1 -
 math/GradientModel.cpp         |  28 ++++---
 routing/CognitiveMapRouter.cpp |   4 -
 routing/CognitiveMapRouter.h   |   1 -
 routing/DirectionStrategy.cpp  |   5 ++
 routing/DummyRouter.cpp        |   3 -
 routing/DummyRouter.h          |   1 -
 routing/GlobalRouter.cpp       |   3 -
 routing/GlobalRouter.h         |   2 -
 routing/MeshRouter.cpp         |   3 -
 routing/MeshRouter.h           |   1 -
 routing/Router.h               |   7 --
 routing/RoutingEngine.cpp      |   5 --
 routing/RoutingEngine.h        |   5 --
 routing/ffRouter.cpp           | 136 ++++++++++++---------------------
 routing/ffRouter.h             |   8 --
 16 files changed, 73 insertions(+), 140 deletions(-)

diff --git a/Simulation.cpp b/Simulation.cpp
index f4979881..fe6d6fd2 100644
--- a/Simulation.cpp
+++ b/Simulation.cpp
@@ -420,7 +420,6 @@ void Simulation::RunHeader(long nPed)
 
     //first initialisation needed by the linked-cells
     UpdateRoutesAndLocations();
-    _routingEngine.get()->PrepareForSimulation(_building.get());
     ProcessAgentsQueue();
 }
 
diff --git a/math/GradientModel.cpp b/math/GradientModel.cpp
index 1aa84115..8c4d1862 100644
--- a/math/GradientModel.cpp
+++ b/math/GradientModel.cpp
@@ -120,6 +120,7 @@ bool GradientModel::Init (Building* building)
 
      std::set<std::pair<int, int>> roomsDoorsSet;
      roomsDoorsSet.clear();
+     // @todo f.mack parallelize? yes, using pedsToRemove should be fine
     for(unsigned int p=0;p<allPeds.size();p++) {
          Pedestrian* ped = allPeds[p];
          double cosPhi, sinPhi;
@@ -165,16 +166,23 @@ bool GradientModel::Init (Building* building)
           std::map<int, std::vector<int>> doorsInRoom;
           doorsInRoom.clear();
           Log->Write("####### The GradientModel is using DirectionLocalFloorfield");
-          // parallelize
-          for (size_t i = 0; i < roomsDoorsSet.size(); ++i) {
-               auto rdIt = roomsDoorsSet.begin();
-               // suboptimal, because a set doesn't provide random-access iterators
-               std::advance(rdIt, i);
-               dirLocff->CalcFloorfield(rdIt->first, rdIt->second);
-               doorsInRoom[rdIt->first].push_back(rdIt->second);
-          }
-          for (auto roomIt : doorsInRoom) {
-               dirLocff->writeFF(roomIt.first, roomIt.second);
+#pragma omp parallel
+          {
+#pragma omp for
+               for (size_t i = 0; i < roomsDoorsSet.size(); ++i) {
+                    auto rdIt = roomsDoorsSet.begin();
+                    // suboptimal, because a set doesn't provide random-access iterators
+                    std::advance(rdIt, i);
+                    dirLocff->CalcFloorfield(rdIt->first, rdIt->second);
+#pragma omp critical(doorsInRoom)
+                    doorsInRoom[rdIt->first].push_back(rdIt->second);
+               }
+#pragma omp for
+               for (size_t i = 0; i < doorsInRoom.size(); ++i) {
+                   auto roomIt = doorsInRoom.begin();
+                   std::advance(roomIt, i);
+                   dirLocff->writeFF(roomIt->first, roomIt->second);
+               }
           }
      }
     return true;
diff --git a/routing/CognitiveMapRouter.cpp b/routing/CognitiveMapRouter.cpp
index 42896c94..dab55db5 100644
--- a/routing/CognitiveMapRouter.cpp
+++ b/routing/CognitiveMapRouter.cpp
@@ -165,10 +165,6 @@ bool CognitiveMapRouter::Init(Building * b)
      return true;
 }
 
-void CognitiveMapRouter::PrepareForSimulation(Building *b) {
-    (void) b;
-}
-
 const optStorage &CognitiveMapRouter::getOptions() const
 {
     return options;
diff --git a/routing/CognitiveMapRouter.h b/routing/CognitiveMapRouter.h
index 942f28cf..dc4a0294 100644
--- a/routing/CognitiveMapRouter.h
+++ b/routing/CognitiveMapRouter.h
@@ -60,7 +60,6 @@ public:
 
      virtual int FindExit(Pedestrian* p);
      virtual bool Init(Building* b);
-     virtual void PrepareForSimulation(Building* b);
 
      /**
       * @return options involved in the routing algorithm
diff --git a/routing/DirectionStrategy.cpp b/routing/DirectionStrategy.cpp
index c3112e8c..9ef574b7 100644
--- a/routing/DirectionStrategy.cpp
+++ b/routing/DirectionStrategy.cpp
@@ -484,7 +484,12 @@ void DirectionLocalFloorfield::CalcFloorfield(int room, int destUID) {
 
 void DirectionLocalFloorfield::writeFF(int room, std::vector<int> targets) {
      std::string lfilename = "floorfield" + std::to_string(room) + ".vtk";
+    std::chrono::time_point<std::chrono::system_clock> start, end;
+    start = std::chrono::system_clock::now();
      locffviafm[room]->writeFF(lfilename, targets);
+    end = std::chrono::system_clock::now();
+    std::chrono::duration<double> elapsed_seconds = end-start;
+    Log->Write("INFO: \twriting %s took %f s ", lfilename.c_str(), elapsed_seconds.count());
 }
 
 DirectionLocalFloorfield::DirectionLocalFloorfield() {
diff --git a/routing/DummyRouter.cpp b/routing/DummyRouter.cpp
index 8bdd7dc0..2d3a01f3 100644
--- a/routing/DummyRouter.cpp
+++ b/routing/DummyRouter.cpp
@@ -75,6 +75,3 @@ bool DummyRouter::Init(Building* b)
      return true;
 }
 
-void DummyRouter::PrepareForSimulation(Building* b) {
-     (void) b;
-}
diff --git a/routing/DummyRouter.h b/routing/DummyRouter.h
index 1e5767af..407d5496 100644
--- a/routing/DummyRouter.h
+++ b/routing/DummyRouter.h
@@ -44,7 +44,6 @@ public:
 
      virtual int FindExit(Pedestrian* p);
      virtual bool Init(Building* b);
-     virtual void PrepareForSimulation(Building* b);
 
 };
 
diff --git a/routing/GlobalRouter.cpp b/routing/GlobalRouter.cpp
index 61d848d2..444d49b7 100644
--- a/routing/GlobalRouter.cpp
+++ b/routing/GlobalRouter.cpp
@@ -547,9 +547,6 @@ void GlobalRouter::Reset(){
      _mapIdToFinalDestination.clear();
 }
 
-void GlobalRouter::PrepareForSimulation(Building* b) {
-     (void) b;
-}
 
 void GlobalRouter::SetEdgeCost(double cost)
 {
diff --git a/routing/GlobalRouter.h b/routing/GlobalRouter.h
index 0109283a..f2c9f9f6 100644
--- a/routing/GlobalRouter.h
+++ b/routing/GlobalRouter.h
@@ -65,8 +65,6 @@ public:
 
      virtual bool Init(Building* building);
 
-     virtual void PrepareForSimulation(Building* b);
-
      virtual int FindExit(Pedestrian* p);
 
      /**
diff --git a/routing/MeshRouter.cpp b/routing/MeshRouter.cpp
index dacf7fba..d391b115 100644
--- a/routing/MeshRouter.cpp
+++ b/routing/MeshRouter.cpp
@@ -968,9 +968,6 @@ bool MeshRouter::Init(Building* b)
      return true;
 }
 
-void MeshRouter::PrepareForSimulation(Building* b) {
-     (void) b;
-}
 
 void MeshRouter::WriteMeshToFile(const string& filename)
 {
diff --git a/routing/MeshRouter.h b/routing/MeshRouter.h
index c83f3e08..18ff19c1 100644
--- a/routing/MeshRouter.h
+++ b/routing/MeshRouter.h
@@ -53,7 +53,6 @@ public:
 
      virtual int FindExit(Pedestrian* p);
      virtual bool Init(Building* b);
-     virtual void PrepareForSimulation(Building* b);
 
 };
 
diff --git a/routing/Router.h b/routing/Router.h
index 53a2c26d..23667eec 100644
--- a/routing/Router.h
+++ b/routing/Router.h
@@ -133,13 +133,6 @@ public:
       */
      virtual bool ParseAdditionalParameters(){return true;};
 
-     /**
-      * Each implementation can do some pre-simulation calculation. When calling this
-      * function, the exit route for each pedestrian (present at the beginning of the
-      * simulation) is already known.
-      */
-     virtual void PrepareForSimulation(Building* b) = 0;
-
 };
 
 #endif  /* _ROUTING_H */
diff --git a/routing/RoutingEngine.cpp b/routing/RoutingEngine.cpp
index 38768f57..d00252fc 100644
--- a/routing/RoutingEngine.cpp
+++ b/routing/RoutingEngine.cpp
@@ -125,8 +125,3 @@ bool RoutingEngine::Init(Building* building)
      return status;
 }
 
-void RoutingEngine::PrepareForSimulation(Building *building) {
-     for (auto router: _routersCollection) {
-          router->PrepareForSimulation(building);
-     }
-}
diff --git a/routing/RoutingEngine.h b/routing/RoutingEngine.h
index bf81f74b..3b39d723 100644
--- a/routing/RoutingEngine.h
+++ b/routing/RoutingEngine.h
@@ -106,11 +106,6 @@ public:
       */
      bool Init(Building* building);
 
-     /**
-      * Allow the routers to do some preparation
-      * @param building
-      */
-     void PrepareForSimulation(Building* building);
 
 private:
      /// collections of all routers used
diff --git a/routing/ffRouter.cpp b/routing/ffRouter.cpp
index 65688e87..4b78909f 100644
--- a/routing/ffRouter.cpp
+++ b/routing/ffRouter.cpp
@@ -562,94 +562,58 @@ bool FFRouter::ReInit()
      return true;
 }
 
-// @todo f.mack remove building from the argument list
-void FFRouter::PrepareForSimulation(Building* building) {}
-
 std::set<std::pair<int, int>> FFRouter::GetPresumableExitRoute(Pedestrian* p) {
-     std::set<std::pair<int, int>> roomsDoorsVector;
-     roomsDoorsVector.clear();
-     // @todo f.mack parallelize
-#pragma omp single
-     {
-          // collects all <room, door> pairs needed using _pathsMatrix
-//          for (auto ped : building->GetAllPedestrians()) {
-               int finalDoor = _finalDoors.at(p->GetID());
-               int finalDoorID = _CroTrByUID.at(finalDoor)->GetID();
-               Log->Write("ped %d: final door is UID %d, ID %d", p->GetID(), finalDoor, finalDoorID);
-               /*
-               if (ped->GetFinalDestination() == -1) {
-                    for (auto lastdoor : validFinalDoorToOutside) {
-
-                    }
-               } else {
-                    finalDoor = goalToLineUIDmap.at(ped->GetFinalDestination());
-               }*/
-               int roomID = p->GetRoomID();
-               auto room = _building->GetRoom(roomID);
-               int doorUID = p->GetNextDestination();
-               do {
-                    Log->Write("PrepareForSimulation: ped %d needs ff in roomID %d to doorUID %d (ID %d)",
+    std::set<std::pair<int, int>> roomsDoorsVector;
+    roomsDoorsVector.clear();
+    int finalDoor = _finalDoors.at(p->GetID());
+    int finalDoorID = _CroTrByUID.at(finalDoor)->GetID();
+    Log->Write("ped %d: final door is UID %d, ID %d", p->GetID(), finalDoor, finalDoorID);
+
+    int roomID = p->GetRoomID();
+    auto room = _building->GetRoom(roomID);
+    int doorUID = p->GetNextDestination();
+    do {
+        Log->Write("GetPresumableExitRoute: ped %d needs ff in roomID %d to doorUID %d (ID %d)",
+              p->GetID(), room->GetID(), doorUID, _CroTrByUID[doorUID]->GetID());
+        if (_CroTrByUID[doorUID]->GetRoom1() &&
+            _CroTrByUID[doorUID]->GetRoom1()->GetID() != room->GetID()) {
+             if (auto tr = dynamic_cast<Transition*>(_CroTrByUID[doorUID])) {
+                  if (tr->GetRoom2() && tr->GetRoom2()->GetID() != room->GetID()) {
+                       Log->Write(
+                               "ERROR in GetPresumableExitRoute: ped %d want to leave roomID %d through doorUID %d (ID %d), but this room does not belong to this door.",
+                               p->GetID(), room->GetID(), doorUID, _CroTrByUID[doorUID]->GetID());
+                  }
+             }
+        }
+        roomsDoorsVector.insert(std::make_pair(room->GetID(), doorUID));
+        auto nextDoorUID = _pathsMatrix.at(std::make_pair(doorUID, finalDoor));
+        // _pathsMatrix sometimes returns a door in the same room we are already in
+        if (!_CroTrByUID[nextDoorUID]->IsInRoom(room->GetID())) {
+             if (Transition* tr = dynamic_cast<Transition*>(_CroTrByUID[doorUID])) {
+                  auto oldRoomID = room->GetID();
+                  room = tr->GetOtherRoom(room->GetID());
+                  if (!tr->IsInRoom(room->GetID())) {
+                       Log->Write("ERROR in GetPresumableExitRoute: ped %d wants to walk through doorUID %d (ID %d), but neither roomID %d nor %d are adjacent.",
+                                  p->GetID(), nextDoorUID, _CroTrByUID[nextDoorUID]->GetID(), oldRoomID, room->GetID());
+                  }
+             }
+        }
+        doorUID = nextDoorUID;
+    } while (doorUID != finalDoor);
+    Log->Write("GetPresumableExitRoute: ped %d needs ff in roomID %d to doorUID %d (ID %d) (final exit)",
+              p->GetID(), room->GetID(), doorUID, _CroTrByUID[doorUID]->GetID());
+    if (_CroTrByUID[doorUID]->GetRoom1() &&
+       _CroTrByUID[doorUID]->GetRoom1()->GetID() != room->GetID()) {
+        if (auto tr = dynamic_cast<Transition*>(_CroTrByUID[doorUID])) {
+             if (tr->GetRoom2() && tr->GetRoom2()->GetID() != room->GetID()) {
+                  Log->Write(
+                          "ERROR in GetPresumableExitRoute: ped %d want to leave roomID %d through doorUID %d (ID %d) (final exit), but this room does not belong to this door.",
                           p->GetID(), room->GetID(), doorUID, _CroTrByUID[doorUID]->GetID());
-                    if (_CroTrByUID[doorUID]->GetRoom1() &&
-                        _CroTrByUID[doorUID]->GetRoom1()->GetID() != room->GetID()) {
-                         if (auto tr = dynamic_cast<Transition*>(_CroTrByUID[doorUID])) {
-                              if (tr->GetRoom2() && tr->GetRoom2()->GetID() != room->GetID()) {
-                                   Log->Write(
-                                           "ERROR in PrepareForSimulation: ped %d want to leave roomID %d through doorUID %d (ID %d), but this room does not belong to this door.",
-                                           p->GetID(), room->GetID(), doorUID, _CroTrByUID[doorUID]->GetID());
-                              }
-                         }
-                    }
-                    roomsDoorsVector.insert(std::make_pair(room->GetID(), doorUID));
-                    auto nextDoorUID = _pathsMatrix.at(std::make_pair(doorUID, finalDoor));
-                    // _pathsMatrix sometimes returns a door in the same room we are already in
-                    if (!_CroTrByUID[nextDoorUID]->IsInRoom(room->GetID())) {
-                         if (Transition* tr = dynamic_cast<Transition*>(_CroTrByUID[doorUID])) {
-                              auto oldRoomID = room->GetID();
-                              room = tr->GetOtherRoom(room->GetID());
-                              if (!tr->IsInRoom(room->GetID())) {
-                                   Log->Write("ERROR in PrepareForSimulation: ped %d wants to walk through doorUID %d (ID %d), but neither roomID %d nor %d are adjacent.",
-                                              p->GetID(), nextDoorUID, _CroTrByUID[nextDoorUID]->GetID(), oldRoomID, room->GetID());
-                              }
-                         }
-                    }
-                    doorUID = nextDoorUID;
-               } while (doorUID != finalDoor);
-               Log->Write("PrepareForSimulation: ped %d needs ff in roomID %d to doorUID %d (ID %d) (final exit)",
-                          p->GetID(), room->GetID(), doorUID, _CroTrByUID[doorUID]->GetID());
-               if (_CroTrByUID[doorUID]->GetRoom1() &&
-                   _CroTrByUID[doorUID]->GetRoom1()->GetID() != room->GetID()) {
-                    if (auto tr = dynamic_cast<Transition*>(_CroTrByUID[doorUID])) {
-                         if (tr->GetRoom2() && tr->GetRoom2()->GetID() != room->GetID()) {
-                              Log->Write(
-                                      "ERROR in PrepareForSimulation: ped %d want to leave roomID %d through doorUID %d (ID %d) (final exit), but this room does not belong to this door.",
-                                      p->GetID(), room->GetID(), doorUID, _CroTrByUID[doorUID]->GetID());
-                         }
-                    }
-               }
-               roomsDoorsVector.insert(std::make_pair(room->GetID(), doorUID));
-//          }
-//
-//          // make entries unique // @todo f.mack maybe using a set is more efficient
-////#pragma omp single
-//          std::sort(roomsDoorsVector.begin(), roomsDoorsVector.end());
-////#pragma omp single
-//          roomsDoorsVector.erase(std::unique(roomsDoorsVector.begin(), roomsDoorsVector.end()), roomsDoorsVector.end());
-//
-//          for (auto sdIt : roomsDoorsVector) {
-//               Log->Write("need ff in roomID %d for doorUID %d (ID %d)",
-//                          sdIt.first, building->GetRoom(sdIt.first)->GetID(), sdIt.second, _CroTrByUID[sdIt.second]->GetID());
-//          }
-//
-//
-//          // calculate the ff in a parallelized way
-//          for (auto rdIt = roomsDoorsVector.begin(); rdIt < roomsDoorsVector.end(); ++rdIt) {
-//               auto newLocFloorfield = new LocalFloorfieldViaFM(building->GetRoom(rdIt->first), building, 0,0,0,true);
-//#pragma omp critical
-//               //_locffviafm.insert();
-//          }
-     } // omp single (is going to become omp parallel)
-     return roomsDoorsVector;
+             }
+        }
+    }
+    roomsDoorsVector.insert(std::make_pair(room->GetID(), doorUID));
+    return roomsDoorsVector;
 }
 
 int FFRouter::FindExit(Pedestrian* p)
diff --git a/routing/ffRouter.h b/routing/ffRouter.h
index 685971c0..094e2c4c 100644
--- a/routing/ffRouter.h
+++ b/routing/ffRouter.h
@@ -153,14 +153,6 @@ public:
       */
      virtual bool ReInit();
 
-     /*!
-      * \brief Calculates some needed floorfields
-      *
-      * PrepareForSimulation() will look up the exit route of each pedestrian (which is not yet
-      * known in Init()) and calculate the floorfields needed for these routes.
-      */
-     virtual void PrepareForSimulation(Building* building);
-
      /*!
       * \brief interface used by __Pedestrian__, sets (*p).exitline/.exitindex
       *
-- 
GitLab