mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 18:45:43 +00:00
Merge branch 'master' of https://gitlab.kitware.com/vtk/vtk-m into particleAdvectionStatus
This commit is contained in:
commit
22becf6de3
@ -306,12 +306,25 @@ template <typename ArrayHandleType>
|
||||
using ArrayHandlePassThrough =
|
||||
vtkm::cont::ArrayHandleTransform<ArrayHandleType, PassThroughFunctor, PassThroughFunctor>;
|
||||
|
||||
template <typename ValueType, vtkm::IdComponent>
|
||||
struct JunkArrayHandle : vtkm::cont::ArrayHandle<ValueType>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
using BMArrayHandleMultiplexer =
|
||||
vtkm::ListTagApply<vtkm::ListTagAppend<vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays<
|
||||
typename ArrayHandleType::ValueType>,
|
||||
ArrayHandlePassThrough<ArrayHandleType>>,
|
||||
vtkm::cont::ArrayHandleMultiplexer>;
|
||||
vtkm::cont::ArrayHandleMultiplexer<ArrayHandleType,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 0>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 1>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 2>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 3>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 4>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 5>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 6>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 7>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 8>,
|
||||
JunkArrayHandle<typename ArrayHandleType::ValueType, 9>,
|
||||
ArrayHandlePassThrough<ArrayHandleType>>;
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
BMArrayHandleMultiplexer<ArrayHandleType> make_ArrayHandleMultiplexer0(const ArrayHandleType& array)
|
||||
|
@ -96,47 +96,6 @@ indices = indicesInMemory;
|
||||
|
||||
All the code that uses `indices` will continue to work.
|
||||
|
||||
If `ArrayHandleMultiplexer` is created with only a single template
|
||||
parameter, then the parameter is interpreted differently. Instead of being
|
||||
interpreted as a type of array, it is interpreted as the `ValueType` of the
|
||||
array. In this case, a default set of arrays will set for you. The basic
|
||||
storage type array will always be part of this list.
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::ArrayHandleMultiplexer<vtkm::FloatDefault> multiplexerArray;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> basicArray;
|
||||
// Fill basicArray...
|
||||
|
||||
multiplexerArray = basicArray;
|
||||
```
|
||||
|
||||
The default list of arrays includes `ArrayHandleCast` from pretty much any
|
||||
basic type of the same vector length. This allows you to get an
|
||||
`ArrayHandleMultiplexer` of some known type and then use it for other
|
||||
types. For example, you can use an integer-based array in a place where you
|
||||
expect a floating point field.
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::ArrayHandleMultiplexer<vtkm::FloatDefault> multiplexerArray;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Int32> integerField;
|
||||
// Fill integerField...
|
||||
|
||||
multiplexerArray = vtkm::cont::make_ArrayHandleCast<vtkm::FloatDefault>(integerField);
|
||||
```
|
||||
|
||||
We (as developers) also have the option of putting in special storage types
|
||||
for particular value types. For example, the default list of arrays for a
|
||||
`Vec<FloatDefault,3>` include `ArrayHandleUniformPointCoordinates` (whereas
|
||||
this array cannot be placed in other default lists).
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::ArrayHandleMultiplexer<vtkm::Vec<vtkm::FloatDefault, 3>> multiplexerArray;
|
||||
|
||||
multiplexerArray = vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(50));
|
||||
```
|
||||
|
||||
## Variant
|
||||
|
||||
To implement `ArrayHandleMultiplexer`, the class `vtkm::internal::Variant`
|
||||
|
@ -375,13 +375,18 @@ private:
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename ValueType, typename... ArrayHandleTypes>
|
||||
template <typename... ArrayHandleTypes>
|
||||
struct ArrayHandleMultiplexerTraits
|
||||
{
|
||||
// If there is a compile error in this group of lines, then the list tag given to
|
||||
// ArrayHandleMultiplexer must contain an invalid ArrayHandle. That could mean that
|
||||
// it is not an ArrayHandle type or it could mean that the value type does not match
|
||||
// the appropriate value type.
|
||||
using ArrayHandleType0 =
|
||||
brigand::at<brigand::list<ArrayHandleTypes...>, std::integral_constant<vtkm::IdComponent, 0>>;
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType0);
|
||||
using ValueType = typename ArrayHandleType0::ValueType;
|
||||
|
||||
// If there is a compile error in this group of lines, then one of the array types given to
|
||||
// ArrayHandleMultiplexer must contain an invalid ArrayHandle. That could mean that it is not an
|
||||
// ArrayHandle type or it could mean that the value type does not match the appropriate value
|
||||
// type.
|
||||
template <typename ArrayHandle>
|
||||
struct CheckArrayHandleTransform
|
||||
{
|
||||
@ -409,154 +414,6 @@ struct ArrayHandleMultiplexerTraits
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief Base implementation of \c ArrayHandleMultiplexer.
|
||||
///
|
||||
/// This behavies the same as \c ArrayHandleMultiplexer, but the template parameters are
|
||||
/// more explicit. The first template parameter must be the \c ValueType of the array.
|
||||
/// The remaining template parameters are the array handles to support.
|
||||
///
|
||||
template <typename ValueType_, typename... ArrayHandleTypes>
|
||||
class ArrayHandleMultiplexerBase
|
||||
: public vtkm::cont::ArrayHandle<
|
||||
ValueType_,
|
||||
typename detail::ArrayHandleMultiplexerTraits<ValueType_, ArrayHandleTypes...>::StorageTag>
|
||||
{
|
||||
using Traits = detail::ArrayHandleMultiplexerTraits<ValueType_, ArrayHandleTypes...>;
|
||||
|
||||
public:
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexerBase,
|
||||
(ArrayHandleMultiplexerBase<ValueType_, ArrayHandleTypes...>),
|
||||
(vtkm::cont::ArrayHandle<ValueType_, typename Traits::StorageTag>));
|
||||
|
||||
private:
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
|
||||
public:
|
||||
template <typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexerBase(
|
||||
const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
|
||||
: Superclass(StorageType(src))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexerBase(vtkm::cont::ArrayHandle<ValueType, RealStorageTag>&& rhs)
|
||||
: Superclass(StorageType(std::move(rhs)))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename ValueType>
|
||||
struct MakeArrayListFromStorage
|
||||
{
|
||||
template <typename S>
|
||||
using Transform = vtkm::cont::ArrayHandle<ValueType, S>;
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
struct SupportedArrays
|
||||
: vtkm::ListTagTransform<vtkm::cont::StorageListTagSupported,
|
||||
MakeArrayListFromStorage<ValueType>::template Transform>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename DestType, typename SrcTypeList>
|
||||
struct MakeCastArrayListImpl
|
||||
{
|
||||
using TypeStoragePairs = vtkm::ListCrossProduct<SrcTypeList, vtkm::cont::StorageListTagSupported>;
|
||||
|
||||
template <typename Pair>
|
||||
struct PairToCastArrayImpl;
|
||||
template <typename T, typename S>
|
||||
struct PairToCastArrayImpl<brigand::list<T, S>>
|
||||
{
|
||||
using Type = vtkm::cont::ArrayHandleCast<DestType, vtkm::cont::ArrayHandle<T, S>>;
|
||||
};
|
||||
template <typename Pair>
|
||||
using PairToCastArray = typename PairToCastArrayImpl<Pair>::Type;
|
||||
|
||||
using Type = vtkm::ListTagTransform<TypeStoragePairs, PairToCastArray>;
|
||||
};
|
||||
|
||||
template <typename DestType>
|
||||
struct MakeCastArrayList
|
||||
{
|
||||
using Type = typename MakeCastArrayListImpl<DestType, vtkm::TypeListTagScalarAll>::Type;
|
||||
};
|
||||
|
||||
template <typename ComponentType, vtkm::IdComponent N>
|
||||
struct MakeCastArrayList<vtkm::Vec<ComponentType, N>>
|
||||
{
|
||||
template <typename T>
|
||||
using ScalarToVec = vtkm::Vec<T, N>;
|
||||
using SourceTypes = vtkm::ListTagTransform<vtkm::TypeListTagScalarAll, ScalarToVec>;
|
||||
|
||||
using Type = typename MakeCastArrayListImpl<vtkm::Vec<ComponentType, N>, SourceTypes>::Type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ArrayHandleMultiplexerDefaultArraysBase
|
||||
: vtkm::ListTagJoin<SupportedArrays<T>, typename MakeCastArrayList<T>::Type>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
struct ArrayHandleMultiplexerDefaultArrays : detail::ArrayHandleMultiplexerDefaultArraysBase<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ArrayHandleMultiplexerDefaultArrays<vtkm::Vec<vtkm::FloatDefault, 3>>
|
||||
: vtkm::ListTagJoin<
|
||||
detail::ArrayHandleMultiplexerDefaultArraysBase<vtkm::Vec<vtkm::FloatDefault, 3>>,
|
||||
vtkm::ListTagBase<
|
||||
#if 1
|
||||
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>,
|
||||
#endif
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates>>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename ValueType, typename ListTagArrays>
|
||||
struct ArrayHandleMultiplexerChooseBaseImpl
|
||||
{
|
||||
VTKM_IS_LIST_TAG(ListTagArrays);
|
||||
|
||||
template <typename BrigandListArrays>
|
||||
struct BrigandListArraysToArrayHandleMultiplexerBase;
|
||||
|
||||
template <typename... ArrayHandleTypes>
|
||||
struct BrigandListArraysToArrayHandleMultiplexerBase<brigand::list<ArrayHandleTypes...>>
|
||||
{
|
||||
using Type = vtkm::cont::ArrayHandleMultiplexerBase<ValueType, ArrayHandleTypes...>;
|
||||
};
|
||||
|
||||
using Type = typename BrigandListArraysToArrayHandleMultiplexerBase<
|
||||
vtkm::internal::ListTagAsBrigandList<ListTagArrays>>::Type;
|
||||
};
|
||||
|
||||
template <typename ValueType>
|
||||
using ArrayHandleMultiplexerChooseBase = typename ArrayHandleMultiplexerChooseBaseImpl<
|
||||
ValueType,
|
||||
internal::ArrayHandleMultiplexerDefaultArrays<ValueType>>::Type;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief An ArrayHandle that can behave like several other handles.
|
||||
///
|
||||
/// An \c ArrayHandleMultiplexer simply redirects its calls to another \c ArrayHandle. However
|
||||
@ -568,58 +425,41 @@ using ArrayHandleMultiplexerChooseBase = typename ArrayHandleMultiplexerChooseBa
|
||||
/// see which type of array is currently stored in it. It then redirects to the \c ArrayHandle
|
||||
/// of the appropriate type.
|
||||
///
|
||||
/// The \c ArrayHandleMultiplexer template parameters are all the ArrayHandle types it
|
||||
/// should support.
|
||||
///
|
||||
/// If only one template parameter is given, it is assumed to be the \c ValueType of the
|
||||
/// array. A default list of supported arrays is supported (see
|
||||
/// \c vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays.) If multiple template
|
||||
/// parameters are given, they are all considered possible \c ArrayHandle types.
|
||||
///
|
||||
template <typename... Ts>
|
||||
class ArrayHandleMultiplexer;
|
||||
|
||||
template <typename ValueType_>
|
||||
class ArrayHandleMultiplexer<ValueType_>
|
||||
: public detail::ArrayHandleMultiplexerChooseBase<ValueType_>
|
||||
template <typename... ArrayHandleTypes>
|
||||
class ArrayHandleMultiplexer
|
||||
: public vtkm::cont::ArrayHandle<
|
||||
typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::ValueType,
|
||||
typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::StorageTag>
|
||||
{
|
||||
using Traits = detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>;
|
||||
|
||||
public:
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexer,
|
||||
(ArrayHandleMultiplexer<ValueType_>),
|
||||
(detail::ArrayHandleMultiplexerChooseBase<ValueType_>));
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(
|
||||
ArrayHandleMultiplexer,
|
||||
(ArrayHandleMultiplexer<ArrayHandleTypes...>),
|
||||
(vtkm::cont::ArrayHandle<typename Traits::ValueType, typename Traits::StorageTag>));
|
||||
|
||||
template <typename RealT, typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<RealT, RealStorageTag>& src)
|
||||
: Superclass(src)
|
||||
{
|
||||
}
|
||||
private:
|
||||
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
|
||||
|
||||
template <typename RealT, typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<RealT, RealStorageTag>&& rhs)
|
||||
: Superclass(std::move(rhs))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArrayType0, typename... ArrayTypes>
|
||||
class ArrayHandleMultiplexer<ArrayType0, ArrayTypes...>
|
||||
: public vtkm::cont::ArrayHandleMultiplexerBase<typename ArrayType0::ValueType,
|
||||
ArrayType0,
|
||||
ArrayTypes...>
|
||||
{
|
||||
public:
|
||||
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexer,
|
||||
(ArrayHandleMultiplexer<ArrayType0, ArrayTypes...>),
|
||||
(vtkm::cont::ArrayHandleMultiplexerBase<typename ArrayType0::ValueType,
|
||||
ArrayType0,
|
||||
ArrayTypes...>));
|
||||
|
||||
template <typename RealT, typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<RealT, RealStorageTag>& src)
|
||||
: Superclass(src)
|
||||
template <typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
|
||||
: Superclass(StorageType(src))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename RealT, typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<RealT, RealStorageTag>&& rhs)
|
||||
: Superclass(std::move(rhs))
|
||||
template <typename RealStorageTag>
|
||||
VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<ValueType, RealStorageTag>&& rhs)
|
||||
: Superclass(StorageType(std::move(rhs)))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -86,63 +86,7 @@ class TestingArrayHandleMultiplexer
|
||||
CheckArray(multiplexer, array3);
|
||||
}
|
||||
|
||||
static void DefaultScalar()
|
||||
{
|
||||
std::cout << std::endl << "--- Default list for scalars" << std::endl;
|
||||
|
||||
using ValueType = vtkm::FloatDefault;
|
||||
|
||||
vtkm::cont::ArrayHandleMultiplexer<ValueType> multiplexer;
|
||||
|
||||
std::cout << "Basic array type." << std::endl;
|
||||
vtkm::cont::ArrayHandle<ValueType> baseArray;
|
||||
baseArray.Allocate(ARRAY_SIZE);
|
||||
SetPortal(baseArray.GetPortalControl());
|
||||
multiplexer = baseArray;
|
||||
CheckArray(multiplexer, baseArray);
|
||||
|
||||
std::cout << "Cast array type." << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> castArray;
|
||||
castArray.Allocate(ARRAY_SIZE);
|
||||
SetPortal(castArray.GetPortalControl());
|
||||
multiplexer = vtkm::cont::make_ArrayHandleCast<ValueType>(castArray);
|
||||
CheckArray(multiplexer, castArray);
|
||||
}
|
||||
|
||||
static void DefaultVec3()
|
||||
{
|
||||
std::cout << std::endl << "--- Default list for Vec3" << std::endl;
|
||||
|
||||
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
|
||||
|
||||
vtkm::cont::ArrayHandleMultiplexer<ValueType> multiplexer;
|
||||
|
||||
std::cout << "Basic array type." << std::endl;
|
||||
vtkm::cont::ArrayHandle<ValueType> baseArray;
|
||||
baseArray.Allocate(ARRAY_SIZE);
|
||||
SetPortal(baseArray.GetPortalControl());
|
||||
multiplexer = baseArray;
|
||||
CheckArray(multiplexer, baseArray);
|
||||
|
||||
std::cout << "Cast array type." << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> castArray;
|
||||
castArray.Allocate(ARRAY_SIZE);
|
||||
SetPortal(castArray.GetPortalControl());
|
||||
multiplexer = vtkm::cont::make_ArrayHandleCast<ValueType>(castArray);
|
||||
CheckArray(multiplexer, castArray);
|
||||
|
||||
std::cout << "Uniform point coordinates" << std::endl;
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates uniformCoords(vtkm::Id3(3));
|
||||
multiplexer = uniformCoords;
|
||||
CheckArray(multiplexer, uniformCoords);
|
||||
}
|
||||
|
||||
static void TestAll()
|
||||
{
|
||||
BasicSwitch();
|
||||
DefaultScalar();
|
||||
DefaultVec3();
|
||||
}
|
||||
static void TestAll() { BasicSwitch(); }
|
||||
|
||||
public:
|
||||
static int Run(int argc, char* argv[])
|
||||
|
@ -14,6 +14,45 @@
|
||||
|
||||
#include <vtkm/ListTag.h>
|
||||
|
||||
|
||||
// It would make sense to put this in its own header file, but it is hard to imagine needing
|
||||
// aligned_union anywhere else.
|
||||
#if (defined(VTKM_GCC) && (__GNUC__ == 4)) || (defined(VTKM_ICC) && (__INTEL_COMPILER < 1800))
|
||||
#include <algorithm>
|
||||
namespace vtkmstd
|
||||
{
|
||||
template <std::size_t... Xs>
|
||||
struct max_size;
|
||||
template <std::size_t X>
|
||||
struct max_size<X>
|
||||
{
|
||||
static constexpr std::size_t value = X;
|
||||
};
|
||||
template <std::size_t X0, std::size_t... Xs>
|
||||
struct max_size<X0, Xs...>
|
||||
{
|
||||
static constexpr std::size_t other_value = max_size<Xs...>::value;
|
||||
static constexpr std::size_t value = (other_value > X0) ? other_value : X0;
|
||||
};
|
||||
// This implementation comes from https://en.cppreference.com/w/cpp/types/aligned_union
|
||||
template <std::size_t Len, class... Types>
|
||||
struct aligned_union
|
||||
{
|
||||
static constexpr std::size_t alignment_value = vtkmstd::max_size<alignof(Types)...>::value;
|
||||
|
||||
struct type
|
||||
{
|
||||
alignas(alignment_value) char _s[vtkmstd::max_size<Len, sizeof(Types)...>::value];
|
||||
};
|
||||
};
|
||||
} // namespace vtkmstd
|
||||
#else
|
||||
namespace vtkmstd
|
||||
{
|
||||
using std::aligned_union;
|
||||
} // namespace vtkmstd
|
||||
#endif
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace internal
|
||||
@ -51,7 +90,7 @@ class Variant
|
||||
{
|
||||
};
|
||||
|
||||
typename std::aligned_union<0, Ts...>::type Storage;
|
||||
typename vtkmstd::aligned_union<0, Ts...>::type Storage;
|
||||
|
||||
VTKM_EXEC_CONT void* GetPointer() { return reinterpret_cast<void*>(&this->Storage); }
|
||||
VTKM_EXEC_CONT const void* GetPointer() const
|
||||
|
Loading…
Reference in New Issue
Block a user