mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge topic 'intel_compiler_hangs_on_brigand_crossproduct'
f9f205e9 ListCrossProduct now uses a special version for MSVC2013 c02349a8 ListCrossProduct now uses a lazy evaluation implementation 7b1b9e44 Correctly forward rvalue functors when passed to CastAndCall Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1018
This commit is contained in:
commit
a1a23f83d3
@ -94,7 +94,7 @@ VTKM_CONT void ListForEach(Functor&& f, ListTag, Args&&... args)
|
||||
}
|
||||
|
||||
/// Generate a tag that is the cross product of two other tags. The resulting
|
||||
// a tag has the form of Tag< std::pair<A1,B1>, std::pair<A1,B2> .... >
|
||||
// a tag has the form of Tag< brigand::list<A1,B1>, brigand::list<A1,B2> .... >
|
||||
///
|
||||
template <typename ListTag1, typename ListTag2>
|
||||
struct ListCrossProduct : detail::ListRoot
|
||||
|
@ -225,9 +225,9 @@ public:
|
||||
};
|
||||
|
||||
template <typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CoordinateSystem& coords, const Functor& f, Args&&... args)
|
||||
void CastAndCall(const vtkm::cont::CoordinateSystem& coords, Functor&& f, Args&&... args)
|
||||
{
|
||||
coords.GetData().CastAndCall(f, std::forward<Args>(args)...);
|
||||
coords.GetData().CastAndCall(std::forward<Functor>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
namespace internal
|
||||
|
@ -358,7 +358,7 @@ public:
|
||||
/// respectively.
|
||||
///
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCall(const Functor& f, Args&&...) const;
|
||||
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
|
||||
|
||||
/// \brief Create a new array of the same type as this array.
|
||||
///
|
||||
@ -414,15 +414,15 @@ struct DynamicArrayHandleTry
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename... Args>
|
||||
void operator()(std::pair<T, U>&& p, Args&&... args) const
|
||||
void operator()(brigand::list<T, U>, Args&&... args) const
|
||||
{
|
||||
using storage = vtkm::cont::internal::Storage<T, U>;
|
||||
using invalid = typename std::is_base_of<vtkm::cont::internal::UndefinedStorage, storage>::type;
|
||||
this->run(std::forward<decltype(p)>(p), invalid{}, args...);
|
||||
this->run<T, U>(invalid{}, args...);
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename Functor, typename... Args>
|
||||
void run(std::pair<T, U>&&, std::false_type, Functor&& f, bool& called, Args&&... args) const
|
||||
void run(std::false_type, Functor&& f, bool& called, Args&&... args) const
|
||||
{
|
||||
if (!called)
|
||||
{
|
||||
@ -437,7 +437,7 @@ struct DynamicArrayHandleTry
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename... Args>
|
||||
void run(std::pair<T, U>&&, std::true_type, Args&&...) const
|
||||
void run(std::true_type, Args&&...) const
|
||||
{
|
||||
}
|
||||
|
||||
@ -451,7 +451,7 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerB
|
||||
|
||||
template <typename TypeList, typename StorageList>
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(const Functor& f,
|
||||
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functor&& f,
|
||||
Args&&... args) const
|
||||
{
|
||||
//For optimizations we should compile once the cross product for the default types
|
||||
@ -460,8 +460,11 @@ VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(const
|
||||
|
||||
bool called = false;
|
||||
auto* ptr = this->ArrayContainer.get();
|
||||
vtkm::ListForEach(
|
||||
detail::DynamicArrayHandleTry(ptr), crossProduct{}, f, called, std::forward<Args>(args)...);
|
||||
vtkm::ListForEach(detail::DynamicArrayHandleTry(ptr),
|
||||
crossProduct{},
|
||||
std::forward<Functor>(f),
|
||||
called,
|
||||
std::forward<Args>(args)...);
|
||||
if (!called)
|
||||
{
|
||||
// throw an exception
|
||||
|
@ -228,7 +228,7 @@ public:
|
||||
/// behavior from \c CastAndCall.
|
||||
///
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCall(const Functor& f, Args&&...) const;
|
||||
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
|
||||
|
||||
/// \brief Create a new cell set of the same type as this cell set.
|
||||
///
|
||||
@ -302,11 +302,12 @@ struct DynamicCellSetTry
|
||||
|
||||
template <typename CellSetList>
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void DynamicCellSetBase<CellSetList>::CastAndCall(const Functor& f, Args&&... args) const
|
||||
VTKM_CONT void DynamicCellSetBase<CellSetList>::CastAndCall(Functor&& f, Args&&... args) const
|
||||
{
|
||||
bool called = false;
|
||||
detail::DynamicCellSetTry tryCellSet(this->CellSetContainer.get());
|
||||
vtkm::ListForEach(tryCellSet, CellSetList{}, f, called, std::forward<Args>(args)...);
|
||||
vtkm::ListForEach(
|
||||
tryCellSet, CellSetList{}, std::forward<Functor>(f), called, std::forward<Args>(args)...);
|
||||
if (!called)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("Could not find appropriate cast for cell set.");
|
||||
|
@ -402,9 +402,9 @@ private:
|
||||
};
|
||||
|
||||
template <typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::Field& field, const Functor& f, Args&&... args)
|
||||
void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args)
|
||||
{
|
||||
field.GetData().CastAndCall(f, std::forward<Args>(args)...);
|
||||
field.GetData().CastAndCall(std::forward<Functor>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
namespace internal
|
||||
|
@ -48,28 +48,28 @@ class CellSetPermutation;
|
||||
/// DynamicObject's CastAndCall, but specializations of this function exist for
|
||||
/// other classes (e.g. Field, CoordinateSystem, ArrayHandle).
|
||||
template <typename DynamicObject, typename Functor, typename... Args>
|
||||
void CastAndCall(const DynamicObject& dynamicObject, const Functor& f, Args&&... args)
|
||||
void CastAndCall(const DynamicObject& dynamicObject, Functor&& f, Args&&... args)
|
||||
{
|
||||
dynamicObject.CastAndCall(f, std::forward<Args>(args)...);
|
||||
dynamicObject.CastAndCall(std::forward<Functor>(f), std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// A specialization of CastAndCall for basic CoordinateSystem to make
|
||||
/// it be treated just like any other dynamic object
|
||||
// actually implemented in vtkm/cont/CoordinateSystem
|
||||
template <typename Functor, typename... Args>
|
||||
void CastAndCall(const CoordinateSystem& coords, const Functor& f, Args&&... args);
|
||||
void CastAndCall(const CoordinateSystem& coords, Functor&& f, Args&&... args);
|
||||
|
||||
/// A specialization of CastAndCall for basic Field to make
|
||||
/// it be treated just like any other dynamic object
|
||||
// actually implemented in vtkm/cont/Field
|
||||
template <typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::Field& field, const Functor& f, Args&&... args);
|
||||
void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args);
|
||||
|
||||
/// A specialization of CastAndCall for basic ArrayHandle types,
|
||||
/// Since the type is already known no deduction is needed.
|
||||
/// This specialization is used to simplify numerous worklet algorithms
|
||||
template <typename T, typename U, typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, const Functor& f, Args&&... args)
|
||||
void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, Functor&& f, Args&&... args)
|
||||
{
|
||||
f(handle, std::forward<Args>(args)...);
|
||||
}
|
||||
@ -78,9 +78,7 @@ void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, const Functor& f,
|
||||
/// Since the type is already known no deduction is needed.
|
||||
/// This specialization is used to simplify numerous worklet algorithms
|
||||
template <vtkm::IdComponent Dim, typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset,
|
||||
const Functor& f,
|
||||
Args&&... args)
|
||||
void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset, Functor&& f, Args&&... args)
|
||||
{
|
||||
f(cellset, std::forward<Args>(args)...);
|
||||
}
|
||||
@ -90,7 +88,7 @@ void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset,
|
||||
/// This specialization is used to simplify numerous worklet algorithms
|
||||
template <typename ConnectivityStorageTag, typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CellSetSingleType<ConnectivityStorageTag>& cellset,
|
||||
const Functor& f,
|
||||
Functor&& f,
|
||||
Args&&... args)
|
||||
{
|
||||
f(cellset, std::forward<Args>(args)...);
|
||||
@ -101,7 +99,7 @@ void CastAndCall(const vtkm::cont::CellSetSingleType<ConnectivityStorageTag>& ce
|
||||
/// This specialization is used to simplify numerous worklet algorithms
|
||||
template <typename T, typename S, typename U, typename V, typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U, V>& cellset,
|
||||
const Functor& f,
|
||||
Functor&& f,
|
||||
Args&&... args)
|
||||
{
|
||||
f(cellset, std::forward<Args>(args)...);
|
||||
@ -112,7 +110,7 @@ void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U, V>& cellset,
|
||||
/// This specialization is used to simplify numerous worklet algorithms
|
||||
template <typename PermutationType, typename CellSetType, typename Functor, typename... Args>
|
||||
void CastAndCall(const vtkm::cont::CellSetPermutation<PermutationType, CellSetType>& cellset,
|
||||
const Functor& f,
|
||||
Functor&& f,
|
||||
Args&&... args)
|
||||
{
|
||||
f(cellset, std::forward<Args>(args)...);
|
||||
|
@ -210,31 +210,47 @@ VTKM_CONT void ListForEachImpl(Functor&& f,
|
||||
std::forward<Functor>(f), brigand::list<ArgTypes...>{}, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename U, typename R>
|
||||
struct ListCrossProductAppend
|
||||
{
|
||||
using type = brigand::push_back<T, std::pair<U, R>>;
|
||||
};
|
||||
|
||||
template <typename T, typename U, typename R2>
|
||||
struct ListCrossProductImplUnrollR2
|
||||
{
|
||||
using P =
|
||||
brigand::fold<R2,
|
||||
brigand::list<>,
|
||||
ListCrossProductAppend<brigand::_state, brigand::_element, brigand::pin<U>>>;
|
||||
|
||||
using type = brigand::append<T, P>;
|
||||
};
|
||||
|
||||
template <typename R1, typename R2>
|
||||
struct ListCrossProductImpl
|
||||
{
|
||||
using type = brigand::fold<
|
||||
R2,
|
||||
brigand::list<>,
|
||||
ListCrossProductImplUnrollR2<brigand::_state, brigand::_element, brigand::pin<R1>>>;
|
||||
#if defined(VTKM_MSVC) && _MSC_VER == 1800
|
||||
// This is a Cartesian product generator that is used
|
||||
// when building with visual studio 2013. Visual Studio
|
||||
// 2013 is unable to handle the lazy version as it can't
|
||||
// deduce the correct template parameters
|
||||
using type = brigand::reverse_fold<
|
||||
brigand::list<R1, R2>,
|
||||
brigand::list<brigand::list<>>,
|
||||
brigand::bind<
|
||||
brigand::join,
|
||||
brigand::bind<
|
||||
brigand::transform,
|
||||
brigand::_2,
|
||||
brigand::defer<brigand::bind<
|
||||
brigand::join,
|
||||
brigand::bind<
|
||||
brigand::transform,
|
||||
brigand::parent<brigand::_1>,
|
||||
brigand::defer<brigand::bind<
|
||||
brigand::list,
|
||||
brigand::bind<brigand::push_front, brigand::_1, brigand::parent<brigand::_1>>>>>>>>>>;
|
||||
#else
|
||||
// This is a lazy Cartesian product generator that is used
|
||||
// when using any compiler other than visual studio 2013.
|
||||
// This version was settled on as being the best default
|
||||
// version as all compilers including Intel handle this
|
||||
// implementation without issue for very large cross products
|
||||
using type = brigand::reverse_fold<
|
||||
brigand::list<R1, R2>,
|
||||
brigand::list<brigand::list<>>,
|
||||
brigand::lazy::join<brigand::lazy::transform<
|
||||
brigand::_2,
|
||||
brigand::defer<brigand::lazy::join<brigand::lazy::transform<
|
||||
brigand::parent<brigand::_1>,
|
||||
brigand::defer<brigand::bind<
|
||||
brigand::list,
|
||||
brigand::lazy::push_front<brigand::_1, brigand::parent<brigand::_1>>>>>>>>>>;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -68,7 +68,7 @@ struct TestListTagUniversal : vtkm::ListTagUniversal
|
||||
};
|
||||
|
||||
template <int N, int M>
|
||||
std::pair<int, int> test_number(std::pair<TestClass<N>, TestClass<M>>)
|
||||
std::pair<int, int> test_number(brigand::list<TestClass<N>, TestClass<M>>)
|
||||
{
|
||||
return std::make_pair(N, M);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user