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

Add ItemArrayUtils for parallelism

This mainly handles the synchronization procedure for ItemArray data.
Thus also implement this special synchronization
parent ee70ba35
Branches
Tags
1 merge request!84Add SubArray class
...@@ -33,13 +33,13 @@ class ItemArray ...@@ -33,13 +33,13 @@ class ItemArray
size_t m_size_of_arrays; size_t m_size_of_arrays;
public:
// Allow const std:shared_ptr version to access our data // Allow const std:shared_ptr version to access our data
friend ItemArray<std::add_const_t<DataType>, item_type, ConnectivitySharedPtr>; friend ItemArray<std::add_const_t<DataType>, item_type, ConnectivitySharedPtr>;
// Allow const std:weak_ptr version to access our data // Allow const std:weak_ptr version to access our data
friend ItemArray<std::add_const_t<DataType>, item_type, ConnectivityWeakPtr>; friend ItemArray<std::add_const_t<DataType>, item_type, ConnectivityWeakPtr>;
public:
friend PUGS_INLINE ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityPtr> friend PUGS_INLINE ItemArray<std::remove_const_t<DataType>, item_type, ConnectivityPtr>
copy(const ItemArray<DataType, item_type, ConnectivityPtr>& source) copy(const ItemArray<DataType, item_type, ConnectivityPtr>& source)
{ {
......
#ifndef ITEM_ARRAY_UTILS_HPP
#define ITEM_ARRAY_UTILS_HPP
#include <utils/Messenger.hpp>
#include <mesh/Connectivity.hpp>
#include <mesh/ItemArray.hpp>
#include <mesh/Synchronizer.hpp>
#include <mesh/SynchronizerManager.hpp>
#include <iostream>
template <typename DataType, ItemType item_type, typename ConnectivityPtr>
void
synchronize(ItemArray<DataType, item_type, ConnectivityPtr>& item_array)
{
static_assert(not std::is_const_v<DataType>, "cannot synchronize ItemArray of const data");
if (parallel::size() > 1) {
auto& manager = SynchronizerManager::instance();
const IConnectivity* connectivity = item_array.connectivity_ptr().get();
Synchronizer& synchronizer = manager.getConnectivitySynchronizer(connectivity);
synchronizer.synchronize(item_array);
}
}
#endif // ITEM_ARRAY_UTILS_HPP
#ifndef ITEM_VALUE_HPP #ifndef ITEM_VALUE_HPP
#define ITEM_VALUE_HPP #define ITEM_VALUE_HPP
#include <utils/Array.hpp>
#include <utils/PugsAssert.hpp>
#include <mesh/IConnectivity.hpp> #include <mesh/IConnectivity.hpp>
#include <mesh/ItemId.hpp> #include <mesh/ItemId.hpp>
#include <mesh/ItemType.hpp> #include <mesh/ItemType.hpp>
#include <utils/Array.hpp>
#include <utils/PugsAssert.hpp>
#include <memory> #include <memory>
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define SYNCHRONIZER_HPP #define SYNCHRONIZER_HPP
#include <mesh/Connectivity.hpp> #include <mesh/Connectivity.hpp>
#include <mesh/ItemArray.hpp>
#include <mesh/ItemValue.hpp> #include <mesh/ItemValue.hpp>
#include <utils/Exceptions.hpp> #include <utils/Exceptions.hpp>
#include <utils/Messenger.hpp> #include <utils/Messenger.hpp>
...@@ -168,6 +169,62 @@ class Synchronizer ...@@ -168,6 +169,62 @@ class Synchronizer
} }
} }
template <typename ConnectivityType, typename DataType, ItemType item_type, typename ConnectivityPtr>
PUGS_INLINE void
_synchronize(const ConnectivityType& connectivity, ItemArray<DataType, item_type, ConnectivityPtr>& item_array)
{
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);
}
const size_t size_of_arrays = item_array.sizeOfArrays();
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>& provided_item_info_to_rank = provided_item_info[i_rank];
Array<DataType> provided_data{provided_item_info_to_rank.size() * size_of_arrays};
parallel_for(
provided_item_info_to_rank.size(), PUGS_LAMBDA(size_t i) {
const size_t j = i * size_of_arrays;
const auto array = item_array[provided_item_info_to_rank[i]];
for (size_t k = 0; k < size_of_arrays; ++k) {
provided_data[j + k] = array[k];
}
});
provided_data_list[i_rank] = provided_data;
}
std::vector<Array<DataType>> requested_data_list(parallel::size());
for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
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() * size_of_arrays};
}
parallel::exchange(provided_data_list, requested_data_list);
for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) {
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(), PUGS_LAMBDA(size_t i) {
const size_t j = i * size_of_arrays;
auto array = item_array[requested_item_info_from_rank[i]];
for (size_t k = 0; k < size_of_arrays; ++k) {
array[k] = requested_data[j + k];
}
});
}
}
public: public:
template <typename DataType, ItemType item_type, typename ConnectivityPtr> template <typename DataType, ItemType item_type, typename ConnectivityPtr>
PUGS_INLINE void PUGS_INLINE void
...@@ -189,9 +246,39 @@ class Synchronizer ...@@ -189,9 +246,39 @@ class Synchronizer
this->_synchronize(static_cast<const Connectivity3D&>(connectivity), item_value); this->_synchronize(static_cast<const Connectivity3D&>(connectivity), item_value);
break; break;
} }
// LCOV_EXCL_START
default: {
throw UnexpectedError("unexpected dimension");
}
// LCOV_EXCL_STOP
}
}
template <typename DataType, ItemType item_type, typename ConnectivityPtr>
PUGS_INLINE void
synchronize(ItemArray<DataType, item_type, ConnectivityPtr>& item_value)
{
Assert(item_value.connectivity_ptr().use_count() > 0, "No connectivity is associated to this ItemValue");
const IConnectivity& connectivity = *item_value.connectivity_ptr();
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;
}
// LCOV_EXCL_START
default: { default: {
throw UnexpectedError("unexpected dimension"); throw UnexpectedError("unexpected dimension");
} }
// LCOV_EXCL_STOP
} }
} }
......
...@@ -101,6 +101,7 @@ add_executable (mpi_unit_tests ...@@ -101,6 +101,7 @@ add_executable (mpi_unit_tests
test_Messenger.cpp test_Messenger.cpp
test_Partitioner.cpp test_Partitioner.cpp
test_ItemArray.cpp test_ItemArray.cpp
test_ItemArrayUtils.cpp
test_ItemValue.cpp test_ItemValue.cpp
test_ItemValueUtils.cpp test_ItemValueUtils.cpp
test_SubItemValuePerItem.cpp test_SubItemValuePerItem.cpp
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment