Skip to content
Snippets Groups Projects
Commit 37167a5f authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Begin Synchronizer clean-up

parent dcfd687d
No related branches found
No related tags found
1 merge request!11Feature/mpi
...@@ -54,46 +54,34 @@ class Synchronizer ...@@ -54,46 +54,34 @@ class Synchronizer
} }
template <typename ConnectivityType, template <typename ConnectivityType,
typename DataType, ItemType item_type>
ItemType item_type, void _buildSynchronizeInfo(const ConnectivityType& connectivity)
typename ConnectivityPtr>
PASTIS_INLINE
void _synchronize(const ConnectivityType& connectivity,
ItemValue<DataType, item_type, ConnectivityPtr>& item_value)
{ {
static_assert(not std::is_abstract_v<ConnectivityType>,
"_synchronize must be called on a concrete connectivity");
using ItemId = ItemIdT<item_type>;
const auto& item_owner = connectivity.template owner<item_type>(); const auto& item_owner = connectivity.template owner<item_type>();
using ItemId = ItemIdT<item_type>;
auto& ghost_items_per_proc = this->_getRequestedItemInfo<item_type>(); auto& requested_item_info = 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"; pout() << "... building synchronization info\n";
ghost_items_per_proc requested_item_info
= [&] () { = [&] () {
std::vector<std::vector<ItemId>> ghost_items_vector_per_proc(parallel::size()); std::vector<std::vector<ItemId>> requested_item_vector_info(parallel::size());
for (ItemId item_id=0; item_id<item_value.size(); ++item_id) { for (ItemId item_id=0; item_id<item_owner.size(); ++item_id) {
if (const size_t owner = item_owner[item_id]; owner != parallel::rank()) { if (const size_t owner = item_owner[item_id]; owner != parallel::rank()) {
ghost_items_vector_per_proc[owner].emplace_back(item_id); requested_item_vector_info[owner].emplace_back(item_id);
} }
} }
std::vector<Array<const ItemId>> ghost_items_per_proc(parallel::size()); std::vector<Array<const ItemId>> requested_item_info(parallel::size());
for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
const auto& ghost_items_vector = ghost_items_vector_per_proc[i_rank]; const auto& requested_item_vector = requested_item_vector_info[i_rank];
ghost_items_per_proc[i_rank] = convert_to_array(ghost_items_vector); requested_item_info[i_rank] = convert_to_array(requested_item_vector);
} }
return ghost_items_per_proc; return requested_item_info;
}(); }();
Array<unsigned int> local_number_of_requested_values(parallel::size()); Array<unsigned int> local_number_of_requested_values(parallel::size());
for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { 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(); local_number_of_requested_values[i_rank] = requested_item_info[i_rank].size();
} }
Array<unsigned int> local_number_of_values_to_send Array<unsigned int> local_number_of_values_to_send
...@@ -102,66 +90,90 @@ class Synchronizer ...@@ -102,66 +90,90 @@ class Synchronizer
std::vector<Array<const int>> requested_item_number_list_by_proc(parallel::size()); std::vector<Array<const int>> requested_item_number_list_by_proc(parallel::size());
const auto& item_number = connectivity.template number<item_type>(); const auto& item_number = connectivity.template number<item_type>();
for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { 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_item_info_from_rank = requested_item_info[i_rank];
Array<int> item_number_list(ghost_items.size()); Array<int> item_number_list{requested_item_info_from_rank.size()};
parallel_for (ghost_items.size(), PASTIS_LAMBDA(size_t i_item) { parallel_for (requested_item_info_from_rank.size(), PASTIS_LAMBDA(size_t i_item) {
item_number_list[i_item] = item_number[ghost_items[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; requested_item_number_list_by_proc[i_rank] = item_number_list;
} }
std::vector<Array<int>> to_send_item_number_list_by_proc(parallel::size());
std::vector<Array<int>> provided_item_number_list_by_rank(parallel::size());
for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { 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]}; 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, to_send_item_number_list_by_proc); parallel::exchange(requested_item_number_list_by_proc, provided_item_number_list_by_rank);
std::map<int, ItemId> item_number_to_id_correspondance; std::map<int, ItemId> item_number_to_id_correspondance;
for (ItemId item_id=0; item_id<item_number.size(); ++item_id) { for (ItemId item_id=0; item_id<item_number.size(); ++item_id) {
item_number_to_id_correspondance[item_number[item_id]] = item_id; item_number_to_id_correspondance[item_number[item_id]] = item_id;
} }
to_send_item_id_list_by_proc auto& provided_item_info = this->_getProvidedItemInfo<item_type>();
provided_item_info
= [&] () { = [&] () {
std::vector<Array<const ItemId>> to_send_item_id_list_by_proc(parallel::size()); std::vector<Array<const ItemId>> provided_item_info(parallel::size());
for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { 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]}; Array<ItemId> provided_item_id_to_rank{local_number_of_values_to_send[i_rank]};
const Array<int>& to_send_item_number = to_send_item_number_list_by_proc[i_rank]; const Array<int>& provided_item_number_to_rank = provided_item_number_list_by_rank[i_rank];
for (size_t i=0; i<to_send_item_number.size(); ++i) { for (size_t i=0; i<provided_item_number_to_rank.size(); ++i) {
to_send_item_id[i] = item_number_to_id_correspondance.find(to_send_item_number[i])->second; provided_item_id_to_rank[i]
= item_number_to_id_correspondance.find(provided_item_number_to_rank[i])->second;
} }
to_send_item_id_list_by_proc[i_rank] = to_send_item_id; provided_item_info[i_rank] = provided_item_id_to_rank;
} }
return to_send_item_id_list_by_proc; return provided_item_info;
} (); } ();
} }
std::vector<Array<const DataType>> to_send_data_by_proc(parallel::size()); template <typename ConnectivityType,
typename DataType,
ItemType item_type,
typename ConnectivityPtr>
PASTIS_INLINE
void _synchronize(const ConnectivityType& connectivity,
ItemValue<DataType, item_type, ConnectivityPtr>& item_value)
{
static_assert(not std::is_abstract_v<ConnectivityType>,
"_synchronize must be called on a concrete connectivity");
using ItemId = ItemIdT<item_type>;
const auto& provided_item_info = this->_getProvidedItemInfo<item_type>();
const auto& requested_item_info = this->_getRequestedItemInfo<item_type>();
Assert(requested_item_info.size() == provided_item_info.size());
if (provided_item_info.size() == 0) {
this->_buildSynchronizeInfo<ConnectivityType, item_type>(connectivity);
}
std::vector<Array<const DataType>> provided_data_list(parallel::size());
for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { 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]; const Array<const ItemId>& provided_item_info_to_rank = provided_item_info[i_rank];
Array<DataType> to_send_data{to_send_item_id.size()}; Array<DataType> provided_data{provided_item_info_to_rank.size()};
parallel_for(to_send_item_id.size(), PASTIS_LAMBDA(size_t i) { parallel_for(provided_item_info_to_rank.size(), PASTIS_LAMBDA(size_t i) {
to_send_data[i] = item_value[to_send_item_id[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) { 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_item_info_from_rank = requested_item_info[i_rank];
requested_data_list_by_proc[i_rank] = Array<DataType>{ghost_items.size()}; 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) { 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_item_info_from_rank = requested_item_info[i_rank];
const auto& requested_data = requested_data_list_by_proc[i_rank]; const auto& requested_data = requested_data_list[i_rank];
parallel_for(ghost_items.size(), PASTIS_LAMBDA(size_t i) { parallel_for(requested_item_info_from_rank.size(), PASTIS_LAMBDA(size_t i) {
item_value[ghost_items[i]] = requested_data[i]; item_value[requested_item_info_from_rank[i]] = requested_data[i];
}); });
requested_data_list_by_proc[i_rank] = Array<DataType>{ghost_items.size()};
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment