Commit c02349a8 authored by Robert Maynard's avatar Robert Maynard
Browse files

ListCrossProduct now uses a lazy evaluation implementation

The intel compiler could not generate code in a timely manner ( 12+ hours ) when
asked to produce a cross product of very long lists. By moving to a lazy
evaluation scheme we now have all compilers product a cross product in a
reasonable amount of time ( 2-4 seconds ).

This resolves Issues:
- vtk/vtk-m#190
- vtk/vtk#17196
parent 7b1b9e44
......@@ -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
......
......@@ -414,7 +414,7 @@ struct DynamicArrayHandleTry
}
template <typename T, typename U, typename... Args>
void operator()(std::pair<T, U>, 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;
......
......@@ -210,31 +210,22 @@ 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>>>;
//This is a lazy Cartesian product generator
//that was found inside the brigand apply test and runs on all compilers.
//The original version didn't work with Intel
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>>>>>>>>>>;
};
......
......@@ -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);
}
......
Supports Markdown
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