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

Implement a simple version of ItemValue synchronization

- It remains a very slow implementation since exchange info is computed at each
synchronize call
- Require more validation
parent 86e477f8
Branches
Tags
1 merge request!11Feature/mpi
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <ConnectivityComputer.hpp> #include <ConnectivityComputer.hpp>
#include <vector> #include <vector>
#include <unordered_map>
#include <algorithm> #include <algorithm>
#include <CellType.hpp> #include <CellType.hpp>
...@@ -214,6 +213,24 @@ class Connectivity final ...@@ -214,6 +213,24 @@ class Connectivity final
return m_node_number; return m_node_number;
} }
template <ItemType item_type>
PASTIS_INLINE
const auto& number() const
{
if constexpr(item_type == ItemType::cell) {
return m_cell_number;
} else if constexpr(item_type == ItemType::face) {
return m_face_number;
} else if constexpr(item_type == ItemType::edge) {
return m_edge_number;
} else if constexpr(item_type == ItemType::node) {
return m_node_number;
} else {
static_assert(item_type == ItemType::cell, "unknown ItemType");
return m_cell_number;
}
}
PASTIS_INLINE PASTIS_INLINE
const auto& cellOwner() const const auto& cellOwner() const
{ {
...@@ -242,19 +259,19 @@ class Connectivity final ...@@ -242,19 +259,19 @@ class Connectivity final
template <ItemType item_type> template <ItemType item_type>
PASTIS_INLINE PASTIS_INLINE
ItemValue<const bool, item_type> isOwned() const const auto& owner() const
{ {
if constexpr(item_type == ItemType::cell) { if constexpr(item_type == ItemType::cell) {
return m_cell_is_owned; return m_cell_owner;
} else if constexpr(item_type == ItemType::face) { } else if constexpr(item_type == ItemType::face) {
return m_face_is_owned; return m_face_owner;
} else if constexpr(item_type == ItemType::edge) { } else if constexpr(item_type == ItemType::edge) {
return m_edge_is_owned; return m_edge_owner;
} else if constexpr(item_type == ItemType::node) { } else if constexpr(item_type == ItemType::node) {
return m_node_is_owned; return m_node_owner;
} else { } else {
static_assert(item_type == ItemType::cell, "unknown ItemType"); static_assert(item_type == ItemType::cell, "unknown ItemType");
return {}; return m_cell_owner;
} }
} }
...@@ -284,6 +301,24 @@ class Connectivity final ...@@ -284,6 +301,24 @@ class Connectivity final
return m_node_is_owned; return m_node_is_owned;
} }
template <ItemType item_type>
PASTIS_INLINE
const auto& isOwned() const
{
if constexpr(item_type == ItemType::cell) {
return m_cell_is_owned;
} else if constexpr(item_type == ItemType::face) {
return m_face_is_owned;
} else if constexpr(item_type == ItemType::edge) {
return m_edge_is_owned;
} else if constexpr(item_type == ItemType::node) {
return m_node_is_owned;
} else {
static_assert(item_type == ItemType::cell, "unknown ItemType");
return m_cell_is_owned;
}
}
PASTIS_INLINE PASTIS_INLINE
const bool& isConnectivityMatrixBuilt(const ItemType& item_type_0, const bool& isConnectivityMatrixBuilt(const ItemType& item_type_0,
const ItemType& item_type_1) const const ItemType& item_type_1) const
......
...@@ -4,8 +4,99 @@ ...@@ -4,8 +4,99 @@
#include <ItemValue.hpp> #include <ItemValue.hpp>
#include <Connectivity.hpp> #include <Connectivity.hpp>
#include <unordered_map>
class ItemValueSynchronizer class ItemValueSynchronizer
{ {
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");
const auto& item_owner = connectivity.template owner<item_type>();
using ItemId = ItemIdT<item_type>;
std::vector<std::vector<ItemId>> ghost_items_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_per_proc[owner].emplace_back(item_id);
}
}
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());
for (size_t i_item = 0; i_item<ghost_items.size(); ++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]};
}
parallel::exchange(requested_item_number_list_by_proc, to_send_item_number_list_by_proc);
std::unordered_map<int, ItemId> item_number_to_id_correspondance(connectivity.template numberOf<item_type>());
for (ItemId item_id=0; item_id<item_number.size(); ++item_id) {
item_number_to_id_correspondance[item_number[item_id]] = item_id;
}
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[to_send_item_number[i]];
}
to_send_item_id_list_by_proc[i_rank] = to_send_item_id;
}
std::vector<Array<const DataType>> to_send_data_by_proc(parallel::size());
for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) {
Array<DataType> to_send_data{local_number_of_values_to_send[i_rank]};
const Array<const ItemId>& to_send_item_id = to_send_item_id_list_by_proc[i_rank];
for (size_t i=0; i<to_send_item_id.size(); ++i) {
to_send_data[i] = item_value[to_send_item_id[i]];
}
to_send_data_by_proc[i_rank] = to_send_data;
}
std::vector<Array<DataType>> requested_data_list_by_proc(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()};
}
parallel::exchange(to_send_data_by_proc, requested_data_list_by_proc);
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];
for (size_t i=0; i<ghost_items.size(); ++i) {
item_value[ghost_items[i]] = requested_data[i];
}
requested_data_list_by_proc[i_rank] = Array<DataType>{ghost_items.size()};
}
}
public: public:
template <typename DataType, template <typename DataType,
ItemType item_type, ItemType item_type,
...@@ -13,13 +104,30 @@ class ItemValueSynchronizer ...@@ -13,13 +104,30 @@ class ItemValueSynchronizer
PASTIS_INLINE PASTIS_INLINE
void synchronize(ItemValue<DataType, item_type, ConnectivityPtr>& item_value) void synchronize(ItemValue<DataType, item_type, ConnectivityPtr>& item_value)
{ {
pout() << "Calling synchronize...\n"; static int cpt=0;
auto connectivity_ptr = item_value.connectivity_ptr(); pout() << "Calling synchronize(" << cpt++ << ")...\n";
Assert(connectivity_ptr.use_count()>0, "No connectivity is associated to this ItemValue");
parallel::barrier(); Assert(item_value.connectivity_ptr().use_count()>0, "No connectivity is associated to this ItemValue");
parallel::Messenger::destroy(); const IConnectivity& connectivity = *item_value.connectivity_ptr();
pout() << __FILE__ << ':' << __LINE__ << ": NIY!\n";
std::exit(0); switch (connectivity.dimension()) {
case 1: {
this->_synchronize(static_cast<const Connectivity1D&>(connectivity), item_value);
break;
}
case 2: {
this->_synchronize(static_cast<const Connectivity2D&>(connectivity), item_value);
break;
}
case 3: {
this->_synchronize(static_cast<const Connectivity3D&>(connectivity), item_value);
break;
}
default: {
perr() << __FILE__ << ':' << __LINE__ << ": unexpected dimension\n";
std::terminate();
}
}
} }
PASTIS_INLINE PASTIS_INLINE
......
...@@ -17,8 +17,10 @@ min(const ItemValue<DataType, item_type>& item_value) ...@@ -17,8 +17,10 @@ min(const ItemValue<DataType, item_type>& item_value)
using data_type = std::remove_const_t<typename ItemValueType::data_type>; using data_type = std::remove_const_t<typename ItemValueType::data_type>;
using index_type = typename ItemValueType::index_type; using index_type = typename ItemValueType::index_type;
ItemValue<const bool, item_type> is_owned const auto& is_owned
= [&] (const IConnectivity& connectivity) { = [&] (const IConnectivity& connectivity) {
Assert((connectivity.dimension()>0) and (connectivity.dimension()<=3),
"unexpected connectivity dimension");
switch (connectivity.dimension()) { switch (connectivity.dimension()) {
case 1: { case 1: {
...@@ -37,18 +39,19 @@ min(const ItemValue<DataType, item_type>& item_value) ...@@ -37,18 +39,19 @@ min(const ItemValue<DataType, item_type>& item_value)
break; break;
} }
default: { default: {
Assert((connectivity.dimension()>0) and (connectivity.dimension()<=3), perr() << __FILE__ << ':' << __LINE__ << ": unexpected dimension\n";
"unexpected connectivity dimension"); std::terminate();
return ItemValue<const bool, item_type>{};
} }
} }
} (*item_value.connectivity_ptr()); } (*item_value.connectivity_ptr());
using IsOwnedType = std::remove_reference_t<decltype(is_owned)>;
class ItemValueMin class ItemValueMin
{ {
private: private:
const ItemValueType& m_item_value; const ItemValueType& m_item_value;
const ItemValue<const bool, item_type>& m_is_owned; const IsOwnedType& m_is_owned;
public: public:
PASTIS_INLINE PASTIS_INLINE
...@@ -84,7 +87,7 @@ min(const ItemValue<DataType, item_type>& item_value) ...@@ -84,7 +87,7 @@ min(const ItemValue<DataType, item_type>& item_value)
PASTIS_INLINE PASTIS_INLINE
ItemValueMin(const ItemValueType& item_value, ItemValueMin(const ItemValueType& item_value,
const ItemValue<const bool, item_type>& is_owned) const IsOwnedType& is_owned)
: m_item_value(item_value), : m_item_value(item_value),
m_is_owned(is_owned) m_is_owned(is_owned)
{ {
...@@ -108,8 +111,10 @@ max(const ItemValue<DataType, item_type>& item_value) ...@@ -108,8 +111,10 @@ max(const ItemValue<DataType, item_type>& item_value)
using data_type = std::remove_const_t<typename ItemValueType::data_type>; using data_type = std::remove_const_t<typename ItemValueType::data_type>;
using index_type = typename ItemValueType::index_type; using index_type = typename ItemValueType::index_type;
ItemValue<const bool, item_type> is_owned const auto& is_owned
= [&] (const IConnectivity& connectivity) { = [&] (const IConnectivity& connectivity) {
Assert((connectivity.dimension()>0) and (connectivity.dimension()<=3),
"unexpected connectivity dimension");
switch (connectivity.dimension()) { switch (connectivity.dimension()) {
case 1: { case 1: {
...@@ -128,18 +133,19 @@ max(const ItemValue<DataType, item_type>& item_value) ...@@ -128,18 +133,19 @@ max(const ItemValue<DataType, item_type>& item_value)
break; break;
} }
default: { default: {
Assert((connectivity.dimension()>0) and (connectivity.dimension()<=3), perr() << __FILE__ << ':' << __LINE__ << ": unexpected dimension\n";
"unexpected connectivity dimension"); std::terminate();
return ItemValue<const bool, item_type>{};
} }
} }
} (*item_value.connectivity_ptr()); } (*item_value.connectivity_ptr());
using IsOwnedType = std::remove_reference_t<decltype(is_owned)>;
class ItemValueMax class ItemValueMax
{ {
private: private:
const ItemValueType& m_item_value; const ItemValueType& m_item_value;
const ItemValue<const bool, item_type>& m_is_owned; const IsOwnedType& m_is_owned;
public: public:
PASTIS_INLINE PASTIS_INLINE
...@@ -175,7 +181,7 @@ max(const ItemValue<DataType, item_type>& item_value) ...@@ -175,7 +181,7 @@ max(const ItemValue<DataType, item_type>& item_value)
PASTIS_INLINE PASTIS_INLINE
ItemValueMax(const ItemValueType& item_value, ItemValueMax(const ItemValueType& item_value,
const ItemValue<const bool, item_type>& is_owned) const IsOwnedType& is_owned)
: m_item_value(item_value), : m_item_value(item_value),
m_is_owned(is_owned) m_is_owned(is_owned)
{ {
...@@ -200,8 +206,10 @@ sum(const ItemValue<DataType, item_type>& item_value) ...@@ -200,8 +206,10 @@ sum(const ItemValue<DataType, item_type>& item_value)
using data_type = std::remove_const_t<typename ItemValueType::data_type>; using data_type = std::remove_const_t<typename ItemValueType::data_type>;
using index_type = typename ItemValueType::index_type; using index_type = typename ItemValueType::index_type;
ItemValue<const bool, item_type> is_owned const auto& is_owned
= [&] (const IConnectivity& connectivity) { = [&] (const IConnectivity& connectivity) {
Assert((connectivity.dimension()>0) and (connectivity.dimension()<=3),
"unexpected connectivity dimension");
switch (connectivity.dimension()) { switch (connectivity.dimension()) {
case 1: { case 1: {
...@@ -220,18 +228,19 @@ sum(const ItemValue<DataType, item_type>& item_value) ...@@ -220,18 +228,19 @@ sum(const ItemValue<DataType, item_type>& item_value)
break; break;
} }
default: { default: {
Assert((connectivity.dimension()>0) and (connectivity.dimension()<=3), perr() << __FILE__ << ':' << __LINE__ << ": unexpected dimension\n";
"unexpected connectivity dimension"); std::terminate();
return ItemValue<const bool, item_type>{};
} }
} }
} (*item_value.connectivity_ptr()); } (*item_value.connectivity_ptr());
using IsOwnedType = std::remove_reference_t<decltype(is_owned)>;
class ItemValueSum class ItemValueSum
{ {
private: private:
const ItemValueType& m_item_value; const ItemValueType& m_item_value;
const ItemValue<const bool, item_type>& m_is_owned; const IsOwnedType& m_is_owned;
public: public:
PASTIS_INLINE PASTIS_INLINE
...@@ -269,7 +278,7 @@ sum(const ItemValue<DataType, item_type>& item_value) ...@@ -269,7 +278,7 @@ sum(const ItemValue<DataType, item_type>& item_value)
PASTIS_INLINE PASTIS_INLINE
ItemValueSum(const ItemValueType& item_value, ItemValueSum(const ItemValueType& item_value,
const ItemValue<const bool, item_type>& is_owned) const IsOwnedType& is_owned)
: m_item_value(item_value), : m_item_value(item_value),
m_is_owned(is_owned) m_is_owned(is_owned)
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment