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