From 35ca89531c0f0fbb84501dd7531567a91ecee924 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 25 Nov 2020 09:02:44 -0700 Subject: [PATCH] Simplify ArrayHandleSwizzle As we update the `ArrayHandle`s to the new buffer style, simplify `ArrayHandleSwizzle` by implementing it on top of `ArrayHandleTransform`. Also, introduce some C++11 template concepts to handle variable arguments better. In this conversion, some features have been removed. Previously if the swizzle dropped some components, you were still allowed to write to the array. This would be an in place write that would only update the passed components. This feature has been removed and if any components are dropped, the array becomes read only. If all components are swizzled, then the array becomes writable (through templating). Another lost feature is that the swizzle map is no longer checked for correctness. The array handle just assumes that the indices are correct. It should be noted that it does not look like `ArrayHandleSwizzle` is actually used anywhere. If it is not used by any customers, we may want to consider deprecating the class. --- vtkm/cont/ArrayHandleSwizzle.h | 538 ++++++------------ vtkm/cont/ArrayHandleTransform.h | 4 +- .../testing/UnitTestArrayHandleSwizzle.cxx | 88 +-- .../UnitTestSerializationArrayHandle.cxx | 19 + 4 files changed, 212 insertions(+), 437 deletions(-) diff --git a/vtkm/cont/ArrayHandleSwizzle.h b/vtkm/cont/ArrayHandleSwizzle.h index 03b9c6919..f1b722ce5 100644 --- a/vtkm/cont/ArrayHandleSwizzle.h +++ b/vtkm/cont/ArrayHandleSwizzle.h @@ -10,365 +10,202 @@ #ifndef vtk_m_cont_ArrayHandleSwizzle_h #define vtk_m_cont_ArrayHandleSwizzle_h -#include -#include +#include + #include -#include -#include +#include -#include +namespace vtkm +{ +namespace internal +{ + +template +class SwizzleFunctor +{ + using InTraits = vtkm::VecTraits; + using InComponentType = typename InTraits::ComponentType; + static constexpr vtkm::IdComponent NUM_IN_COMPONENTS = InTraits::NUM_COMPONENTS; + + using OutTraits = vtkm::VecTraits; + using OutComponentType = typename OutTraits::ComponentType; + static constexpr vtkm::IdComponent NUM_OUT_COMPONENTS = OutTraits::NUM_COMPONENTS; + + template + using IndexSequence = vtkmstd::integer_sequence; + using IndexList = vtkmstd::make_integer_sequence; + +public: + using MapType = vtkm::Vec; + + VTKM_CONT SwizzleFunctor(const MapType& map) + : Map(map) + { + } + + VTKM_CONT SwizzleFunctor() = default; + + VTKM_EXEC_CONT OutType operator()(const InType& vec) const + { + return this->Swizzle(vec, IndexList{}); + } + + VTKM_CONT static MapType InitMap() { return IndexListAsMap(IndexList{}); } + +private: + template + VTKM_CONT static MapType IndexListAsMap(IndexSequence) + { + return { Is... }; + } + + template + VTKM_EXEC_CONT OutType Swizzle(const InType& vec, IndexSequence) const + { + return { InTraits::GetComponent(vec, this->Map[Is])... }; + } + + MapType Map = InitMap(); +}; + +namespace detail +{ + +template +struct GetInverseSwizzleImpl; + +template +struct GetInverseSwizzleImpl +{ + using Type = vtkm::internal::SwizzleFunctor; + template + VTKM_CONT static Type Value(const ForwardMapType& forwardMap) + { + // Note that when reversing the map, if the forwardMap repeats any indices, then + // the map is not 1:1 and is not invertible. We cannot check that at compile time. + // In this case, results can become unpredictible. + using InverseMapType = typename Type::MapType; + InverseMapType inverseMap = Type::InitMap(); + for (vtkm::IdComponent inIndex = 0; inIndex < ForwardMapType::NUM_COMPONENTS; ++inIndex) + { + inverseMap[forwardMap[inIndex]] = inIndex; + } + + return Type(inverseMap); + } +}; + +template +struct GetInverseSwizzleImpl +{ + using Type = vtkm::cont::internal::NullFunctorType; + template + VTKM_CONT static Type Value(const ForwardMapType&) + { + return Type{}; + } +}; + +template +using SwizzleInvertible = std::integral_constant::NUM_COMPONENTS == + vtkm::VecTraits::NUM_COMPONENTS>; + +} // namespace detail + +template +VTKM_CONT vtkm::internal::SwizzleFunctor GetSwizzleFunctor( + const typename vtkm::internal::SwizzleFunctor::MapType& forwardMap) +{ + return vtkm::internal::SwizzleFunctor(forwardMap); +} + +template +using InverseSwizzleType = typename detail:: + GetInverseSwizzleImpl>::Type; + +template +VTKM_CONT InverseSwizzleType GetInverseSwizzleFunctor( + const typename vtkm::internal::SwizzleFunctor::MapType& forwardMap) +{ + return detail:: + GetInverseSwizzleImpl>::Value( + forwardMap); +} + +} +} // namespace vtkm::internal namespace vtkm { namespace cont { -template -struct ResizeVectorType +namespace detail { -private: - using ComponentType = typename vtkm::VecTraits::ComponentType; - -public: - using Type = vtkm::Vec; -}; - -template -class StorageTagSwizzle -{ -}; - -namespace internal -{ - -template -struct ArrayHandleSwizzleTraits; - -template -struct ArrayHandleSwizzleTraits, S>, OutSize> -{ - using ComponentType = V; - static constexpr vtkm::IdComponent InVecSize = C; - static constexpr vtkm::IdComponent OutVecSize = OutSize; - - VTKM_STATIC_ASSERT(OutVecSize <= InVecSize); - static constexpr bool AllCompsUsed = (InVecSize == OutVecSize); - - using InValueType = vtkm::Vec; - using OutValueType = vtkm::Vec; - - using InStorageTag = S; - using InArrayHandleType = vtkm::cont::ArrayHandle; - - using OutStorageTag = vtkm::cont::StorageTagSwizzle; - using OutArrayHandleType = vtkm::cont::ArrayHandle; - - using InStorageType = vtkm::cont::internal::Storage; - using OutStorageType = vtkm::cont::internal::Storage; - - using MapType = vtkm::Vec; - - VTKM_CONT - static void ValidateMap(const MapType& map) - { - for (vtkm::IdComponent i = 0; i < OutVecSize; ++i) - { - if (map[i] < 0 || map[i] >= InVecSize) - { - std::ostringstream error; - error << "Invalid swizzle map: Element " << i << " (" << map[i] - << ") outside valid range [0, " << InVecSize << ")."; - throw vtkm::cont::ErrorBadValue(error.str()); - } - for (vtkm::IdComponent j = i + 1; j < OutVecSize; ++j) - { - if (map[i] == map[j]) - { - std::ostringstream error; - error << "Invalid swizzle map: Repeated element (" << map[i] << ")" - << " at indices " << i << " and " << j << "."; - throw vtkm::cont::ErrorBadValue(error.str()); - } - } - } - } - - VTKM_EXEC_CONT - static void Swizzle(const InValueType& in, OutValueType& out, const MapType& map) - { - for (vtkm::IdComponent i = 0; i < OutSize; ++i) - { - out[i] = in[map[i]]; - } - } - - VTKM_EXEC_CONT - static void UnSwizzle(const OutValueType& out, InValueType& in, const MapType& map) - { - for (vtkm::IdComponent i = 0; i < OutSize; ++i) - { - in[map[i]] = out[i]; - } - } -}; - -template -class VTKM_ALWAYS_EXPORT ArrayPortalSwizzle -{ - using Traits = internal::ArrayHandleSwizzleTraits; - using Writable = vtkm::internal::PortalSupportsSets; - -public: - using MapType = typename Traits::MapType; - using ValueType = typename Traits::OutValueType; - - VTKM_EXEC_CONT - ArrayPortalSwizzle() - : Portal() - , Map() - { - } - - VTKM_EXEC_CONT - ArrayPortalSwizzle(const PortalType& portal, const MapType& map) - : Portal(portal) - , Map(map) - { - } - - // Copy constructor - VTKM_EXEC_CONT ArrayPortalSwizzle(const ArrayPortalSwizzle& src) - : Portal(src.GetPortal()) - , Map(src.GetMap()) - { - } - - ArrayPortalSwizzle& operator=(const ArrayPortalSwizzle& src) = default; - ArrayPortalSwizzle& operator=(ArrayPortalSwizzle&& src) = default; - - VTKM_EXEC_CONT - vtkm::Id GetNumberOfValues() const { return this->Portal.GetNumberOfValues(); } - - VTKM_EXEC_CONT - ValueType Get(vtkm::Id index) const - { - ValueType result; - Traits::Swizzle(this->Portal.Get(index), result, this->Map); - return result; - } - - template ::type> - VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const - { - if (Traits::AllCompsUsed) - { // No need to prefetch the value, all values overwritten - typename Traits::InValueType tmp; - Traits::UnSwizzle(value, tmp, this->Map); - this->Portal.Set(index, tmp); - } - else - { // Not all values used -- need to initialize the vector - typename Traits::InValueType tmp = this->Portal.Get(index); - Traits::UnSwizzle(value, tmp, this->Map); - this->Portal.Set(index, tmp); - } - } - - VTKM_EXEC_CONT - const PortalType& GetPortal() const { return this->Portal; } - - VTKM_EXEC_CONT - const MapType& GetMap() const { return this->Map; } - -private: - PortalType Portal; - MapType Map; -}; template -class Storage::Type, - vtkm::cont::StorageTagSwizzle> +struct ArrayHandleSwizzleTraits { - using Traits = internal::ArrayHandleSwizzleTraits; + VTKM_IS_ARRAY_HANDLE(ArrayHandleType); -public: - using PortalType = - ArrayPortalSwizzle; - using PortalConstType = - ArrayPortalSwizzle; - using MapType = typename Traits::MapType; - using ValueType = typename Traits::OutValueType; + using InType = typename ArrayHandleType::ValueType; + using OutType = vtkm::Vec::ComponentType, OutSize>; + using SwizzleFunctor = vtkm::internal::SwizzleFunctor; + using InverseSwizzleFunctor = vtkm::internal::InverseSwizzleType; + using MapType = typename SwizzleFunctor::MapType; - VTKM_CONT - Storage() - : Valid(false) + static SwizzleFunctor GetFunctor(const MapType& forwardMap) { + return vtkm::internal::GetSwizzleFunctor(forwardMap); } - VTKM_CONT - Storage(const ArrayHandleType& array, const MapType& map) - : Array(array) - , Map(map) - , Valid(true) + static InverseSwizzleFunctor GetInverseFunctor(const MapType& forwardMap) { - Traits::ValidateMap(this->Map); + return vtkm::internal::GetInverseSwizzleFunctor(forwardMap); } - VTKM_CONT - PortalConstType GetPortalConst() const - { - VTKM_ASSERT(this->Valid); - return PortalConstType(this->Array.ReadPortal(), this->Map); - } - - VTKM_CONT - PortalType GetPortal() - { - VTKM_ASSERT(this->Valid); - return PortalType(this->Array.WritePortal(), this->Map); - } - - VTKM_CONT - vtkm::Id GetNumberOfValues() const - { - VTKM_ASSERT(this->Valid); - return this->Array.GetNumberOfValues(); - } - - VTKM_CONT - void Allocate(vtkm::Id numberOfValues) - { - VTKM_ASSERT(this->Valid); - this->Array.Allocate(numberOfValues); - } - - VTKM_CONT - void Shrink(vtkm::Id numberOfValues) - { - VTKM_ASSERT(this->Valid); - this->Array.Shrink(numberOfValues); - } - - VTKM_CONT - void ReleaseResources() - { - VTKM_ASSERT(this->Valid); - this->Array.ReleaseResources(); - } - - VTKM_CONT - const ArrayHandleType& GetArray() const - { - VTKM_ASSERT(this->Valid); - return this->Array; - } - - VTKM_CONT - const MapType& GetMap() const - { - VTKM_ASSERT(this->Valid); - return this->Map; - } - -private: - ArrayHandleType Array; - MapType Map; - bool Valid; + using Superclass = + vtkm::cont::ArrayHandleTransform; }; -template -class ArrayTransfer::Type, - vtkm::cont::StorageTagSwizzle, - DeviceTag> -{ - using InExecTypes = typename ArrayHandleType::template ExecutionTypes; - using Traits = ArrayHandleSwizzleTraits; - using StorageType = typename Traits::OutStorageType; - using MapType = typename Traits::MapType; - - template - using OutExecType = ArrayPortalSwizzle; - -public: - using ValueType = typename Traits::OutValueType; - using PortalControl = typename StorageType::PortalType; - using PortalConstControl = typename StorageType::PortalConstType; - using PortalExecution = OutExecType; - using PortalConstExecution = OutExecType; - - VTKM_CONT - ArrayTransfer(StorageType* storage) - : Array(storage->GetArray()) - , Map(storage->GetMap()) - { - } - - VTKM_CONT - vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); } - - VTKM_CONT - PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData), vtkm::cont::Token& token) - { - return PortalConstExecution(this->Array.PrepareForInput(DeviceTag(), token), this->Map); - } - - VTKM_CONT - PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData), vtkm::cont::Token& token) - { - return PortalExecution(this->Array.PrepareForInPlace(DeviceTag(), token), this->Map); - } - - VTKM_CONT - PortalExecution PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::Token& token) - { - return PortalExecution(this->Array.PrepareForOutput(numberOfValues, DeviceTag(), token), - this->Map); - } - - VTKM_CONT - void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const - { - // Implementation of this method should be unnecessary. The internal - // array handle should automatically retrieve the output data as - // necessary. - } - - VTKM_CONT - void Shrink(vtkm::Id numberOfValues) { this->Array.Shrink(numberOfValues); } - - VTKM_CONT - void ReleaseResources() { this->Array.ReleaseResourcesExecution(); } - - -private: - ArrayHandleType Array; - MapType Map; -}; - -} // end namespace internal +} // namespace detail +/// \brief Swizzle the components of the values in an `ArrayHandle`. +/// +/// Given an `ArrayHandle` with `Vec` values, `ArrayHandleSwizzle` allows you to +/// reorder the components of all the `Vec` values. This reordering is done in place, +/// so the array does not have to be duplicated. +/// +/// The resulting array does not have to contain all of the components of the input. +/// For example, you could use `ArrayHandleSwizzle` to drop one of the components of +/// each vector. However, if you do that, then the swizzled array is read-only. If +/// there is a 1:1 map from input components to output components, writing to the +/// array will be enabled. +/// +/// The swizzle map given to `ArrayHandleSwizzle` must comprise valid component indices +/// (between 0 and number of components - 1). Also, the component indices should not +/// be repeated, particularly if you expect to write to the array. These conditions are +/// not checked. +/// template class ArrayHandleSwizzle - : public ArrayHandle< - typename ResizeVectorType::Type, - vtkm::cont::StorageTagSwizzle> + : public detail::ArrayHandleSwizzleTraits::Superclass { + VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + + using Traits = detail::ArrayHandleSwizzleTraits; + public: - using SwizzleTraits = internal::ArrayHandleSwizzleTraits; - using StorageType = typename SwizzleTraits::OutStorageType; - using MapType = typename SwizzleTraits::MapType; + VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleSwizzle, + (ArrayHandleSwizzle), + (typename Traits::Superclass)); - VTKM_ARRAY_HANDLE_SUBCLASS( - ArrayHandleSwizzle, - (ArrayHandleSwizzle), - (ArrayHandle::Type, - vtkm::cont::StorageTagSwizzle>)); + using MapType = typename Traits::MapType; - VTKM_CONT - ArrayHandleSwizzle(const ArrayHandleType& array, const MapType& map) - : Superclass(StorageType(array, map)) + VTKM_CONT ArrayHandleSwizzle(const ArrayHandleType& array, const MapType& map) + : Superclass(array, Traits::GetFunctor(map), Traits::GetInverseFunctor(map)) { } }; @@ -400,22 +237,20 @@ namespace vtkm namespace cont { -template -struct SerializableTypeString> +template +struct SerializableTypeString> { static VTKM_CONT const std::string& Get() { - static std::string name = - "AH_Swizzle<" + SerializableTypeString::Get() + "," + std::to_string(NComps) + ">"; + static std::string name = "Swizzle<" + SerializableTypeString::Get() + "," + + SerializableTypeString::Get() + ">"; return name; } }; template -struct SerializableTypeString::ComponentType, NComps>, - vtkm::cont::StorageTagSwizzle>> - : SerializableTypeString> +struct SerializableTypeString> + : SerializableTypeString::Superclass> { }; } @@ -426,34 +261,7 @@ namespace mangled_diy_namespace template struct Serialization> -{ -private: - using Type = vtkm::cont::ArrayHandleSwizzle; - using BaseType = vtkm::cont::ArrayHandle; - -public: - static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj) - { - auto storage = obj.GetStorage(); - vtkmdiy::save(bb, storage.GetArray()); - vtkmdiy::save(bb, storage.GetMap()); - } - - static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj) - { - AH array; - vtkmdiy::load(bb, array); - vtkm::Vec map; - vtkmdiy::load(bb, map); - obj = vtkm::cont::make_ArrayHandleSwizzle(array, map); - } -}; - -template -struct Serialization::ComponentType, NComps>, - vtkm::cont::StorageTagSwizzle>> - : Serialization> + : Serialization::Superclass> { }; diff --git a/vtkm/cont/ArrayHandleTransform.h b/vtkm/cont/ArrayHandleTransform.h index 7a40e8fd8..ef1a8299f 100644 --- a/vtkm/cont/ArrayHandleTransform.h +++ b/vtkm/cont/ArrayHandleTransform.h @@ -662,7 +662,9 @@ private: public: VTKM_CONT - ArrayHandleTransform(const ArrayHandleType& handle, const FunctorType& functor = FunctorType()) + ArrayHandleTransform(const ArrayHandleType& handle, + const FunctorType& functor = FunctorType{}, + internal::NullFunctorType = internal::NullFunctorType{}) : Superclass(StorageType(handle, functor)) { } diff --git a/vtkm/cont/testing/UnitTestArrayHandleSwizzle.cxx b/vtkm/cont/testing/UnitTestArrayHandleSwizzle.cxx index 8d854973c..4c34bfaf4 100644 --- a/vtkm/cont/testing/UnitTestArrayHandleSwizzle.cxx +++ b/vtkm/cont/testing/UnitTestArrayHandleSwizzle.cxx @@ -24,7 +24,8 @@ namespace template struct SwizzleTests { - using SwizzleInputArrayType = vtkm::cont::ArrayHandle>; + static constexpr vtkm::IdComponent InSize = 4; + using SwizzleInputArrayType = vtkm::cont::ArrayHandle>; template using SwizzleArrayType = vtkm::cont::ArrayHandleSwizzle; @@ -69,20 +70,6 @@ struct SwizzleTests template void SanityCheck(const MapType& map) const { - using Swizzle = SwizzleArrayType; - using Traits = typename Swizzle::SwizzleTraits; - - VTKM_TEST_ASSERT(Traits::OutVecSize == - vtkm::VecTraits::NUM_COMPONENTS, - "Traits::OutVecSize invalid."); - VTKM_TEST_ASSERT( - VTKM_PASS_COMMAS(std::is_same::value), - "Traits::ComponentType invalid."); - VTKM_TEST_ASSERT( - VTKM_PASS_COMMAS( - std::is_same>::value), - "Traits::OutValueType invalid."); - SwizzleInputArrayType input = this->BuildSwizzleInputArray(); auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map); @@ -93,8 +80,6 @@ struct SwizzleTests template void ReadTest(const MapType& map) const { - using Traits = typename SwizzleArrayType::SwizzleTraits; - // Test that the expected values are read from an Swizzle array. SwizzleInputArrayType input = this->BuildSwizzleInputArray(); auto swizzle = vtkm::cont::make_ArrayHandleSwizzle(input, map); @@ -103,7 +88,7 @@ struct SwizzleTests this->ValidateReadTest(swizzle, map); // Copy the extracted array in the execution environment to test reading: - vtkm::cont::ArrayHandle execCopy; + vtkm::cont::ArrayHandle> execCopy; Algo::Copy(swizzle, execCopy); this->ValidateReadTest(execCopy, map); } @@ -111,9 +96,8 @@ struct SwizzleTests template void ValidateReadTest(ArrayHandleType testArray, const MapType& map) const { - using Traits = typename SwizzleArrayType::SwizzleTraits; using ReferenceVectorType = typename ReferenceArrayType::ValueType; - using SwizzleVectorType = typename Traits::OutValueType; + using SwizzleVectorType = vtkm::Vec; VTKM_TEST_ASSERT(map.GetNumberOfComponents() == vtkm::VecTraits::NUM_COMPONENTS, @@ -171,7 +155,7 @@ struct SwizzleTests template - void WriteTest(const MapType& map) const + void WriteTest(const MapType& map, std::true_type) const { // Control test: { @@ -201,6 +185,18 @@ struct SwizzleTests } } + template + void WriteTest(const MapType&, std::false_type) const + { + // Array is not writable + } + + template + void WriteTest(const MapType& map) const + { + this->WriteTest(map, std::integral_constant{}); + } + // Check that the swizzled components are twice the reference value. template void ValidateWriteTestArray(SwizzleInputArrayType testArray, const MapType& map) const @@ -318,59 +314,9 @@ void TestArrayHandleSwizzle() vtkm::testing::Testing::TryTypes(ArgToTemplateType(), TestTypes()); } -void TestComponentMapValidator() -{ - vtkm::cont::ArrayHandle dummy; - - // Repeat components: - bool error = false; - try - { - vtkm::cont::make_ArrayHandleSwizzle(dummy, 0, 1, 2, 1); - error = true; - } - catch (vtkm::cont::ErrorBadValue& e) - { - std::cout << "Caught expected exception 1: " << e.what() << "\n"; - } - VTKM_TEST_ASSERT(!error, "Repeat components allowed."); - - try - { - vtkm::cont::make_ArrayHandleSwizzle(dummy, 0, 1, 2, -1); - error = true; - } - catch (vtkm::cont::ErrorBadValue& e) - { - std::cout << "Caught expected exception 2: " << e.what() << "\n"; - } - VTKM_TEST_ASSERT(!error, "Negative components allowed."); - - try - { - vtkm::cont::make_ArrayHandleSwizzle(dummy, 0, 1, 2, 5); - error = true; - } - catch (vtkm::cont::ErrorBadValue& e) - { - std::cout << "Caught expected exception 3: " << e.what() << "\n"; - } - VTKM_TEST_ASSERT(!error, "Invalid component allowed."); -} - } // end anon namespace int UnitTestArrayHandleSwizzle(int argc, char* argv[]) { - try - { - TestComponentMapValidator(); - } - catch (vtkm::cont::Error& e) - { - std::cerr << "Error: " << e.what() << "\n"; - return EXIT_FAILURE; - } - return vtkm::cont::testing::Testing::Run(TestArrayHandleSwizzle, argc, argv); } diff --git a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx index 7d628dc02..e27b51f91 100644 --- a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx @@ -336,6 +336,22 @@ struct TestArrayHandleReverse } }; +struct TestArrayHandleSwizzle +{ + template + void operator()(T) const + { + constexpr vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits::NUM_COMPONENTS; + vtkm::Vec map; + for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i) + { + map[i] = NUM_COMPONENTS - (i + 1); + } + auto array = vtkm::cont::make_ArrayHandleSwizzle(RandomArrayHandle::Make(ArraySize), map); + RunTest(array); + } +}; + vtkm::cont::ArrayHandleUniformPointCoordinates MakeRandomArrayHandleUniformPointCoordinates() { @@ -393,6 +409,9 @@ void TestArrayHandleSerialization() std::cout << "Testing ArrayHandleReverse\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleReverse(), TestTypesList()); + std::cout << "Testing ArrayHandleSwizzle\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleSwizzle(), TestTypesList()); + std::cout << "Testing ArrayHandleUniformPointCoordinates\n"; TestArrayHandleUniformPointCoordinates(); }