Commit 1bd74413 authored by Robert Maynard's avatar Robert Maynard Committed by Kitware Robot
Browse files

Merge topic 'more_efficient_dynamicarrayhandle_cast_call'

c026d14b

 DynamicArrayHandle prunes invalid Value/Storage set before cast and call
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Kenneth Moreland's avatarKenneth Moreland <kmorel@sandia.gov>
Merge-request: !1109
parents 66e356f7 c026d14b
......@@ -58,20 +58,28 @@ class VTKM_CONT_EXPORT ArrayHandleBase
{
};
/// Checks to see if the given type and storage can form a valid array handle
/// Checks to see if the given type and storage forms a valid array handle
/// (some storage objects cannot support all types). This check is compatible
/// with C++11 type_traits. It contains a
/// typedef named type that is either std::true_type or std::false_type.
/// Both of these have a typedef named value with the respective boolean value.
/// with C++11 type_traits.
///
template <typename T, typename StorageTag>
struct IsValidArrayHandle
{
//need to add the not
using type =
std::integral_constant<bool,
: std::integral_constant<bool,
!(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T, StorageTag>>::value)>;
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
{
};
/// Checks to see if the given type and storage forms a invalid array handle
/// (some storage objects cannot support all types). This check is compatible
/// with C++11 type_traits.
///
template <typename T, typename StorageTag>
struct IsInValidArrayHandle
: std::integral_constant<bool,
(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
{
};
/// Checks to see if the ArrayHandle for the given DeviceAdatper allows
......@@ -97,6 +105,7 @@ private:
public:
using type = std::integral_constant<bool, !IsVoidType::value>;
static constexpr bool value = !IsVoidType::value;
};
/// Checks to see if the given object is an array handle. This check is
......
......@@ -29,6 +29,7 @@
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/StorageListTag.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/internal/DynamicTransform.h>
namespace vtkm
......@@ -408,26 +409,17 @@ namespace detail
struct DynamicArrayHandleTry
{
DynamicArrayHandleTry(const PolymorphicArrayHandleContainerBase* const c)
: Container(c)
{
}
template <typename T, typename U, typename... Args>
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<T, U>(invalid{}, args...);
}
template <typename T, typename U, typename Functor, typename... Args>
void run(std::false_type, Functor&& f, bool& called, Args&&... args) const
void operator()(brigand::list<T, U>,
Functor&& f,
bool& called,
const PolymorphicArrayHandleContainerBase* const container,
Args&&... args) const
{
if (!called)
{
using downcastType = const vtkm::cont::detail::PolymorphicArrayHandleContainer<T, U>* const;
downcastType downcastContainer = dynamic_cast<downcastType>(this->Container);
downcastType downcastContainer = dynamic_cast<downcastType>(container);
if (downcastContainer)
{
f(downcastContainer->Array, std::forward<Args>(args)...);
......@@ -435,13 +427,6 @@ struct DynamicArrayHandleTry
}
}
}
template <typename T, typename U, typename... Args>
void run(std::true_type, Args&&...) const
{
}
const PolymorphicArrayHandleContainerBase* const Container;
};
VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerBase*,
......@@ -449,6 +434,25 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerB
const std::type_info*);
} // namespace detail
template <typename T>
struct IsUndefinedStorage
{
};
template <typename T, typename U>
struct IsUndefinedStorage<brigand::list<T, U>> : vtkm::cont::internal::IsInValidArrayHandle<T, U>
{
};
template <typename TypeList, typename StorageList>
struct ListTagDynamicTypes : vtkm::detail::ListRoot
{
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
// using list = typename crossProduct::list;
using list = ::brigand::remove_if<typename crossProduct::list, IsUndefinedStorage<brigand::_1>>;
};
template <typename TypeList, typename StorageList>
template <typename Functor, typename... Args>
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functor&& f,
......@@ -456,14 +460,15 @@ VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functo
{
//For optimizations we should compile once the cross product for the default types
//and make it extern
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
using crossProduct = ListTagDynamicTypes<TypeList, StorageList>;
bool called = false;
auto* ptr = this->ArrayContainer.get();
vtkm::ListForEach(detail::DynamicArrayHandleTry(ptr),
vtkm::ListForEach(detail::DynamicArrayHandleTry{},
crossProduct{},
std::forward<Functor>(f),
called,
ptr,
std::forward<Args>(args)...);
if (!called)
{
......
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