Commit d5ccdf54 authored by Linus Seelinger's avatar Linus Seelinger

Refactored GatherScatter backwards compatibility using is_detected_v

parent ff532ff5
Pipeline #31146 failed with stage
in 5 minutes and 35 seconds
......@@ -6,6 +6,7 @@ install(FILES
collectivecommunication.hh
communication.hh
communicator.hh
gatherscatterbackwardscompat.hh
indexset.hh
indicessyncer.hh
interface.hh
......
......@@ -15,6 +15,7 @@
#include <mpi.h>
#include <dune/common/exceptions.hh>
#include <dune/common/parallel/gatherscatterbackwardscompat.hh>
#include <dune/common/parallel/interface.hh>
#include <dune/common/parallel/remoteindices.hh>
#include <dune/common/stdstreams.hh>
......@@ -1260,24 +1261,6 @@ namespace Dune
return entries;
}
template <typename T>
struct has4ArgGather {
struct Any { template <typename U> operator U( void ); };
struct AnyRef { template <typename U> operator U&( void ); };
// Check for size function argument pattern
template<typename U>
static int32_t SFINAE(decltype(std::declval<U>().gather(AnyRef(), Any(), Any(), Any()))*);
template<typename U>
static int32_t SFINAE(decltype(std::declval<U>().gather(Any(), Any(), Any(), Any()))*);
template<typename U>
static int8_t SFINAE(...);
static const bool value = sizeof(SFINAE<T>(nullptr)) == sizeof(int32_t);
};
template<class Data, class GatherScatter, bool FORWARD>
inline void BufferedCommunicator::MessageGatherer<Data,GatherScatter,FORWARD,VariableSize>::operator()(const InterfaceMap& interfaces,const Data& data, Type* buffer, size_t bufferSize) const
{
......@@ -1303,7 +1286,7 @@ namespace Dune
#ifdef DUNE_ISTL_WITH_CHECKING
assert(bufferSize>=(index+1)*sizeof(typename CommPolicy<Data>::IndexedType));
#endif
if constexpr (has4ArgGather<GatherScatter>::value)
if constexpr (Impl::isValidWithArgs<GatherScatter, Impl::DetectedGather>(Impl::Any(), Impl::Any(), Impl::Any(), Impl::Any()))
buffer[index]=GatherScatter::gather(data, local, j, interfacePair->first);
else
buffer[index]=GatherScatter::gather(data, local, j);
......@@ -1314,24 +1297,6 @@ namespace Dune
}
template <typename T>
struct has3ArgGather {
struct Any { template <typename U> operator U( void ); };
struct AnyRef { template <typename U> operator U&( void ); };
// Check for size function argument pattern
template<typename U>
static int32_t SFINAE(decltype(std::declval<U>().gather(AnyRef(), Any(), Any()))*);
template<typename U>
static int32_t SFINAE(decltype(std::declval<U>().gather(Any(), Any(), Any()))*);
template<typename U>
static int8_t SFINAE(...);
static const bool value = sizeof(SFINAE<T>(nullptr)) == sizeof(int32_t);
};
template<class Data, class GatherScatter, bool FORWARD>
inline void BufferedCommunicator::MessageGatherer<Data,GatherScatter,FORWARD,SizeOne>::operator()(const InterfaceMap& interfaces, const Data& data, Type* buffer, size_t bufferSize) const
{
......@@ -1355,7 +1320,7 @@ namespace Dune
assert(bufferSize>=(index+1)*sizeof(typename CommPolicy<Data>::IndexedType));
#endif
if constexpr (has3ArgGather<GatherScatter>::value)
if constexpr (Impl::isValidWithArgs<GatherScatter, Impl::DetectedGather>(Impl::Any(), Impl::Any(), Impl::Any()))
buffer[index++] = GatherScatter::gather(data, FORWARD ? interfacePair->second.first[i] :
interfacePair->second.second[i], interfacePair->first);
else
......@@ -1366,25 +1331,6 @@ namespace Dune
}
template <typename T>
struct has5ArgScatter {
struct Any { template <typename U> operator U( void ); };
struct AnyRef { template <typename U> operator U&( void ); };
// Check for size function argument pattern
template<typename U>
static int32_t SFINAE(decltype(std::declval<U>().scatter(AnyRef(), Any(), Any(), Any(), Any()))*);
template<typename U>
static int32_t SFINAE(decltype(std::declval<U>().scatter(Any(), Any(), Any(), Any(), Any()))*);
template<typename U>
static int8_t SFINAE(...);
static const bool value = sizeof(SFINAE<T>(nullptr)) == sizeof(int32_t);
};
template<class Data, class GatherScatter, bool FORWARD>
inline void BufferedCommunicator::MessageScatterer<Data,GatherScatter,FORWARD,VariableSize>::operator()(const InterfaceMap& interfaces, Data& data, Type* buffer, const int& proc) const
{
......@@ -1398,7 +1344,7 @@ namespace Dune
for(size_t i=0, index=0; i < info.size(); i++) {
for(size_t j=0; j < CommPolicy<Data>::getSize(data, info[i]); j++) {
if constexpr (has5ArgScatter<GatherScatter>::value)
if constexpr (Impl::isValidWithArgs<GatherScatter, Impl::DetectedScatter>(Impl::AnyRef(), Impl::Any(), Impl::Any(), Impl::Any(), Impl::Any()))
GatherScatter::scatter(data, buffer[index++], info[i], j, proc);
else
GatherScatter::scatter(data, buffer[index++], info[i], j);
......@@ -1406,24 +1352,6 @@ namespace Dune
}
}
template <typename T>
struct has4ArgScatter {
struct Any { template <typename U> operator U( void ); };
struct AnyRef { template <typename U> operator U&( void ); };
// Check for scatter function pattern
template<typename U>
static int32_t SFINAE(decltype(U::scatter(AnyRef(), Any(), Any(), Any()))*);
template<typename U>
static int32_t SFINAE(decltype(U::scatter(Any(), Any(), Any(), Any()))*);
template<typename U>
static int8_t SFINAE(...);
static const bool value = sizeof(SFINAE<T>(nullptr)) == sizeof(int32_t);
};
template<class Data, class GatherScatter, bool FORWARD>
inline void BufferedCommunicator::MessageScatterer<Data,GatherScatter,FORWARD,SizeOne>::operator()(const InterfaceMap& interfaces, Data& data, Type* buffer, const int& proc) const
{
......@@ -1436,7 +1364,7 @@ namespace Dune
infoPair->second.first;
for(size_t i=0; i < info.size(); i++) {
if constexpr (has4ArgScatter<GatherScatter>::value)
if constexpr (Impl::isValidWithArgs<GatherScatter, Impl::DetectedScatter>(Impl::Any(), Impl::Any(), Impl::Any(), Impl::Any()))
GatherScatter::scatter(data, buffer[i], info[i], proc);
else
GatherScatter::scatter(data, buffer[i], info[i]);
......
#ifndef DUNE_GATHERSCATTERBACKWARDSCOMPAT
#define DUNE_GATHERSCATTERBACKWARDSCOMPAT
#include <utility>
#include <dune/common/std/type_traits.hh>
namespace Dune {
// Tools for backwards compatibility with GatherScatter interface not receiving sender/receiver ranks
namespace Impl {
struct Any { template <typename U> operator U( void ); };
struct AnyRef { template <typename U> operator U&( void ); };
template<class T, template<class...> class Op, class... Args>
constexpr bool isValidWithArgs(Args&&...)
{ return Std::is_detected_v<Op, T, Args...>; }
template<class T, class... Args>
using DetectedGather = decltype(std::declval<T>().gather(std::forward<Args>(std::declval<Args>())...));
template<class T, class... Args>
using DetectedScatter = decltype(std::declval<T>().scatter(std::forward<Args>(std::declval<Args>())...));
template<class T, class... Args>
using DetectedSize = decltype(std::declval<T>().size(std::forward<Args>(std::declval<Args>())...));
}
}
#endif
......@@ -17,6 +17,7 @@
#include <mpi.h>
#include <dune/common/parallel/gatherscatterbackwardscompat.hh>
#include <dune/common/parallel/interface.hh>
#include <dune/common/parallel/mpitraits.hh>
#include <dune/common/unused.hh>
......@@ -537,21 +538,6 @@ private:
/** @} */
template <typename T>
struct has2ArgSize {
struct Any { template <typename U> operator U( void ); };
// Check for size function argument pattern
template<typename U>
static int32_t SFINAE(decltype(std::declval<U>().size(Any(), Any()))*);
template<typename U>
static int8_t SFINAE(...);
static const bool value = sizeof(SFINAE<T>(nullptr)) == sizeof(int32_t);
};
namespace
{
/**
......@@ -580,7 +566,7 @@ public:
template<class B>
void gather(B& buf, int i, int proc)
{
if constexpr (has2ArgSize<DataHandle>::value)
if constexpr (Impl::isValidWithArgs<DataHandle, Impl::DetectedSize>(Impl::Any(), Impl::Any()))
buf.write(data_.size(i, proc));
else
buf.write(data_.size(i));
......@@ -687,7 +673,7 @@ struct PackEntries
std::size_t noIndices=std::min(buffer.size()/tracker.fixedSize, tracker.indicesLeft());
for(std::size_t i=0; i< noIndices; ++i)
{
if constexpr (has2ArgSize<DataHandle>::value)
if constexpr (Impl::isValidWithArgs<DataHandle, Impl::DetectedSize>(Impl::Any(), Impl::Any()))
handle.gather(buffer, tracker.index(), tracker.rank());
else
handle.gather(buffer, tracker.index());
......@@ -699,7 +685,7 @@ struct PackEntries
{
int packed=0;
tracker.skipZeroIndices();
if constexpr (has2ArgSize<DataHandle>::value) {
if constexpr (Impl::isValidWithArgs<DataHandle, Impl::DetectedSize>(Impl::Any(), Impl::Any())) {
while(!tracker.finished())
if(buffer.hasSpaceForItems(handle.size(tracker.index(), tracker.rank())))
{
......@@ -751,7 +737,7 @@ struct UnpackEntries{
for(std::size_t i=0; i< noIndices; ++i)
{
if constexpr (has2ArgSize<DataHandle>::value)
if constexpr (Impl::isValidWithArgs<DataHandle, Impl::DetectedSize>(Impl::Any(), Impl::Any()))
handle.scatter(buffer, tracker.index(), tracker.fixedSize, tracker.rank());
else
handle.scatter(buffer, tracker.index(), tracker.fixedSize);
......@@ -766,7 +752,7 @@ struct UnpackEntries{
{
assert(!tracker.finished());
assert(buffer.hasSpaceForItems(tracker.size()));
if constexpr (has2ArgSize<DataHandle>::value)
if constexpr (Impl::isValidWithArgs<DataHandle, Impl::DetectedSize>(Impl::Any(), Impl::Any()))
handle.scatter(buffer, tracker.index(), tracker.size(), tracker.rank());
else
handle.scatter(buffer, tracker.index(), tracker.size());
......@@ -859,7 +845,7 @@ struct SetupSendRequest{
int size=PackEntries<DataHandle>()(handle, tracker, buffer);
// Skip indices of zero size.
if constexpr (has2ArgSize<DataHandle>::value) {
if constexpr (Impl::isValidWithArgs<DataHandle, Impl::DetectedSize>(Impl::Any(), Impl::Any())) {
while(!tracker.finished() && !handle.size(tracker.index(), tracker.rank()))
tracker.moveToNextIndex();
} else {
......@@ -1096,7 +1082,7 @@ void VariableSizeCommunicator<Allocator>::setupInterfaceTrackers(DataHandle& han
{
if(handle.fixedsize() && InterfaceInformationChooser<FORWARD>::getSend(inf->second).size()) {
if constexpr (has2ArgSize<DataHandle>::value) {
if constexpr (Impl::isValidWithArgs<DataHandle, Impl::DetectedSize>(Impl::Any(), Impl::Any())) {
fixedsize=handle.size(InterfaceInformationChooser<FORWARD>::getSend(inf->second)[0], inf->first);
} else {
fixedsize=handle.size(InterfaceInformationChooser<FORWARD>::getSend(inf->second)[0]);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment