From 37167a5f9c675eea3402860605f24292c050c54c Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Thu, 28 Feb 2019 18:51:05 +0100
Subject: [PATCH] Begin Synchronizer clean-up

---
 src/mesh/Synchronizer.hpp | 176 ++++++++++++++++++++------------------
 1 file changed, 94 insertions(+), 82 deletions(-)

diff --git a/src/mesh/Synchronizer.hpp b/src/mesh/Synchronizer.hpp
index 87b5c56c9..8f82e3a33 100644
--- a/src/mesh/Synchronizer.hpp
+++ b/src/mesh/Synchronizer.hpp
@@ -53,6 +53,81 @@ class Synchronizer
     }
   }
 
+  template <typename ConnectivityType,
+            ItemType item_type>
+  void _buildSynchronizeInfo(const ConnectivityType& connectivity)
+  {
+    const auto& item_owner =  connectivity.template owner<item_type>();
+    using ItemId = ItemIdT<item_type>;
+
+    auto& requested_item_info = this->_getRequestedItemInfo<item_type>();
+
+    pout() << "... building synchronization info\n";
+    requested_item_info
+        = [&] () {
+            std::vector<std::vector<ItemId>> requested_item_vector_info(parallel::size());
+            for (ItemId item_id=0; item_id<item_owner.size(); ++item_id) {
+              if (const size_t owner = item_owner[item_id]; owner != parallel::rank()) {
+                requested_item_vector_info[owner].emplace_back(item_id);
+              }
+            }
+            std::vector<Array<const ItemId>> requested_item_info(parallel::size());
+            for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+              const auto& requested_item_vector = requested_item_vector_info[i_rank];
+              requested_item_info[i_rank] = convert_to_array(requested_item_vector);
+            }
+            return requested_item_info;
+          }();
+
+    Array<unsigned int> local_number_of_requested_values(parallel::size());
+    for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+      local_number_of_requested_values[i_rank] = requested_item_info[i_rank].size();
+    }
+
+    Array<unsigned int> local_number_of_values_to_send
+        = parallel::allToAll(local_number_of_requested_values);
+
+    std::vector<Array<const int>> requested_item_number_list_by_proc(parallel::size());
+    const auto& item_number = connectivity.template number<item_type>();
+    for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+      const auto& requested_item_info_from_rank = requested_item_info[i_rank];
+      Array<int> item_number_list{requested_item_info_from_rank.size()};
+      parallel_for (requested_item_info_from_rank.size(), PASTIS_LAMBDA(size_t i_item) {
+          item_number_list[i_item] = item_number[requested_item_info_from_rank[i_item]];
+        });
+      requested_item_number_list_by_proc[i_rank] = item_number_list;
+    }
+
+
+    std::vector<Array<int>> provided_item_number_list_by_rank(parallel::size());
+    for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+      provided_item_number_list_by_rank[i_rank] = Array<int>{local_number_of_values_to_send[i_rank]};
+    }
+
+    parallel::exchange(requested_item_number_list_by_proc, provided_item_number_list_by_rank);
+
+    std::map<int, ItemId> item_number_to_id_correspondance;
+    for (ItemId item_id=0; item_id<item_number.size(); ++item_id) {
+      item_number_to_id_correspondance[item_number[item_id]] = item_id;
+    }
+
+    auto& provided_item_info = this->_getProvidedItemInfo<item_type>();
+    provided_item_info
+        = [&] () {
+            std::vector<Array<const ItemId>> provided_item_info(parallel::size());
+            for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
+              Array<ItemId> provided_item_id_to_rank{local_number_of_values_to_send[i_rank]};
+              const Array<int>& provided_item_number_to_rank = provided_item_number_list_by_rank[i_rank];
+              for (size_t i=0; i<provided_item_number_to_rank.size(); ++i) {
+                provided_item_id_to_rank[i]
+                    = item_number_to_id_correspondance.find(provided_item_number_to_rank[i])->second;
+              }
+              provided_item_info[i_rank] = provided_item_id_to_rank;
+            }
+            return provided_item_info;
+          } ();
+  }
+
   template <typename ConnectivityType,
             typename DataType,
             ItemType item_type,
@@ -66,102 +141,39 @@ class Synchronizer
 
     using ItemId = ItemIdT<item_type>;
 
-    const auto& item_owner =  connectivity.template owner<item_type>();
-
-    auto& ghost_items_per_proc = this->_getRequestedItemInfo<item_type>();
-    auto& to_send_item_id_list_by_proc = this->_getProvidedItemInfo<item_type>();
-
-    Assert(ghost_items_per_proc.size() == to_send_item_id_list_by_proc.size());
-
-    if (ghost_items_per_proc.size() == 0) {
-      pout() << "... building synchronization info\n";
-      ghost_items_per_proc
-          = [&] () {
-              std::vector<std::vector<ItemId>> ghost_items_vector_per_proc(parallel::size());
-              for (ItemId item_id=0; item_id<item_value.size(); ++item_id) {
-                if (const size_t owner = item_owner[item_id]; owner != parallel::rank()) {
-                  ghost_items_vector_per_proc[owner].emplace_back(item_id);
-                }
-              }
-              std::vector<Array<const ItemId>> ghost_items_per_proc(parallel::size());
-              for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-                const auto& ghost_items_vector = ghost_items_vector_per_proc[i_rank];
-                ghost_items_per_proc[i_rank] = convert_to_array(ghost_items_vector);
-              }
-              return ghost_items_per_proc;
-            }();
-
-      Array<unsigned int> local_number_of_requested_values(parallel::size());
-      for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-        local_number_of_requested_values[i_rank] = ghost_items_per_proc[i_rank].size();
-      }
-
-      Array<unsigned int> local_number_of_values_to_send
-          = parallel::allToAll(local_number_of_requested_values);
-
-      std::vector<Array<const int>> requested_item_number_list_by_proc(parallel::size());
-      const auto& item_number = connectivity.template number<item_type>();
-      for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-        const auto& ghost_items = ghost_items_per_proc[i_rank];
-        Array<int> item_number_list(ghost_items.size());
-        parallel_for (ghost_items.size(), PASTIS_LAMBDA(size_t i_item) {
-            item_number_list[i_item] = item_number[ghost_items[i_item]];
-          });
-        requested_item_number_list_by_proc[i_rank] = item_number_list;
-      }
-
-      std::vector<Array<int>> to_send_item_number_list_by_proc(parallel::size());
-      for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-        to_send_item_number_list_by_proc[i_rank] = Array<int>{local_number_of_values_to_send[i_rank]};
-      }
+    const auto& provided_item_info = this->_getProvidedItemInfo<item_type>();
+    const auto& requested_item_info = this->_getRequestedItemInfo<item_type>();
 
-      parallel::exchange(requested_item_number_list_by_proc, to_send_item_number_list_by_proc);
+    Assert(requested_item_info.size() == provided_item_info.size());
 
-      std::map<int, ItemId> item_number_to_id_correspondance;
-      for (ItemId item_id=0; item_id<item_number.size(); ++item_id) {
-        item_number_to_id_correspondance[item_number[item_id]] = item_id;
-      }
-
-      to_send_item_id_list_by_proc
-          = [&] () {
-              std::vector<Array<const ItemId>> to_send_item_id_list_by_proc(parallel::size());
-              for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-                Array<ItemId> to_send_item_id{local_number_of_values_to_send[i_rank]};
-                const Array<int>& to_send_item_number = to_send_item_number_list_by_proc[i_rank];
-                for (size_t i=0; i<to_send_item_number.size(); ++i) {
-                  to_send_item_id[i] = item_number_to_id_correspondance.find(to_send_item_number[i])->second;
-                }
-                to_send_item_id_list_by_proc[i_rank] = to_send_item_id;
-              }
-              return to_send_item_id_list_by_proc;
-            } ();
+    if (provided_item_info.size() == 0) {
+      this->_buildSynchronizeInfo<ConnectivityType, item_type>(connectivity);
     }
 
-    std::vector<Array<const DataType>> to_send_data_by_proc(parallel::size());
+    std::vector<Array<const DataType>> provided_data_list(parallel::size());
     for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-      const Array<const ItemId>& to_send_item_id = to_send_item_id_list_by_proc[i_rank];
-      Array<DataType> to_send_data{to_send_item_id.size()};
-      parallel_for(to_send_item_id.size(), PASTIS_LAMBDA(size_t i) {
-          to_send_data[i] = item_value[to_send_item_id[i]];
+      const Array<const ItemId>& provided_item_info_to_rank = provided_item_info[i_rank];
+      Array<DataType> provided_data{provided_item_info_to_rank.size()};
+      parallel_for(provided_item_info_to_rank.size(), PASTIS_LAMBDA(size_t i) {
+          provided_data[i] = item_value[provided_item_info_to_rank[i]];
         });
-      to_send_data_by_proc[i_rank] = to_send_data;
+      provided_data_list[i_rank] = provided_data;
     }
 
-    std::vector<Array<DataType>> requested_data_list_by_proc(parallel::size());
+    std::vector<Array<DataType>> requested_data_list(parallel::size());
     for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-      const auto& ghost_items = ghost_items_per_proc[i_rank];
-      requested_data_list_by_proc[i_rank] = Array<DataType>{ghost_items.size()};
+      const auto& requested_item_info_from_rank = requested_item_info[i_rank];
+      requested_data_list[i_rank] = Array<DataType>{requested_item_info_from_rank.size()};
     }
 
-    parallel::exchange(to_send_data_by_proc, requested_data_list_by_proc);
+    parallel::exchange(provided_data_list, requested_data_list);
 
     for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
-      const auto& ghost_items = ghost_items_per_proc[i_rank];
-      const auto& requested_data = requested_data_list_by_proc[i_rank];
-      parallel_for(ghost_items.size(), PASTIS_LAMBDA(size_t i) {
-          item_value[ghost_items[i]] = requested_data[i];
+      const auto& requested_item_info_from_rank = requested_item_info[i_rank];
+      const auto& requested_data = requested_data_list[i_rank];
+      parallel_for(requested_item_info_from_rank.size(), PASTIS_LAMBDA(size_t i) {
+          item_value[requested_item_info_from_rank[i]] = requested_data[i];
         });
-      requested_data_list_by_proc[i_rank] = Array<DataType>{ghost_items.size()};
     }
   }
 
-- 
GitLab