From e47cedd972c1781d59237f617751debee2b084e8 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 4 Aug 2020 21:16:29 -0600 Subject: [PATCH 01/51] Add UnknownArrayHandle --- vtkm/cont/ArrayHandleMultiplexer.h | 8 +- vtkm/cont/CMakeLists.txt | 2 + vtkm/cont/CastAndCall.h | 13 +- vtkm/cont/UnknownArrayHandle.cxx | 71 +++ vtkm/cont/UnknownArrayHandle.h | 540 ++++++++++++++++++ vtkm/cont/testing/CMakeLists.txt | 1 + .../testing/UnitTestUnknownArrayHandle.cxx | 398 +++++++++++++ 7 files changed, 1029 insertions(+), 4 deletions(-) create mode 100644 vtkm/cont/UnknownArrayHandle.cxx create mode 100644 vtkm/cont/UnknownArrayHandle.h create mode 100644 vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx diff --git a/vtkm/cont/ArrayHandleMultiplexer.h b/vtkm/cont/ArrayHandleMultiplexer.h index 23955f7c9..ef2d4d634 100644 --- a/vtkm/cont/ArrayHandleMultiplexer.h +++ b/vtkm/cont/ArrayHandleMultiplexer.h @@ -176,9 +176,9 @@ struct MultiplexerShrinkFunctor struct MultiplexerReleaseResourcesFunctor { template - VTKM_CONT vtkm::Id operator()(ArrayHandleType&& array) const + VTKM_CONT void operator()(ArrayHandleType&& array) const { - return array.ReleaseResources(); + array.ReleaseResources(); } }; @@ -334,6 +334,10 @@ public: } VTKM_CONT ArrayHandleVariantType& GetArrayHandleVariant() { return this->ArrayHandleVariant; } + VTKM_CONT const ArrayHandleVariantType& GetArrayHandleVariant() const + { + return this->ArrayHandleVariant; + } }; diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index 20eaf866e..3c6f852ef 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -116,6 +116,7 @@ set(headers Token.h TryExecute.h SerializableTypeString.h + UnknownArrayHandle.h VariantArrayHandle.h VirtualObjectHandle.h ) @@ -191,6 +192,7 @@ set(sources RuntimeDeviceInformation.cxx StorageVirtual.cxx Timer.cxx + UnknownArrayHandle.cxx ) #----------------------------------------------------------------------------- diff --git a/vtkm/cont/CastAndCall.h b/vtkm/cont/CastAndCall.h index 4dda44264..4632fe5b6 100644 --- a/vtkm/cont/CastAndCall.h +++ b/vtkm/cont/CastAndCall.h @@ -19,11 +19,13 @@ namespace vtkm namespace cont { +class CoordinateSystem; +class Field; + template class ArrayHandle; -class CoordinateSystem; -class Field; +class UnknownArrayHandle; template class CellSetStructured; @@ -65,6 +67,13 @@ void CastAndCall(const vtkm::cont::ArrayHandle& handle, Functor&& f, Args& f(handle, std::forward(args)...); } +/// A specialization of CastAndCall for UnknownArrayHandle. +/// Since we have no hints on the types, use VTKM_DEFAULT_TYPE_LIST +/// and VTKM_DEFAULT_STORAGE_LIST. +// actually implemented in vtkm/cont/UnknownArrayHandle +template +void CastAndCall(const UnknownArrayHandle& handle, Functor&& f, Args&&... args); + /// A specialization of CastAndCall for basic CellSetStructured types, /// Since the type is already known no deduction is needed. /// This specialization is used to simplify numerous worklet algorithms diff --git a/vtkm/cont/UnknownArrayHandle.cxx b/vtkm/cont/UnknownArrayHandle.cxx new file mode 100644 index 000000000..63636eb94 --- /dev/null +++ b/vtkm/cont/UnknownArrayHandle.cxx @@ -0,0 +1,71 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ + +#include + +namespace vtkm +{ +namespace cont +{ + +namespace detail +{ + +std::shared_ptr UnknownAHContainer::MakeNewInstance() const +{ + // Start by doing an invalid copy to create a new container, then swap out the pointer + // to the array handle to make sure that each object will delete its own ArrayHandle + // when they get destroyed. + std::shared_ptr newContainer(new UnknownAHContainer(*this)); + newContainer->ArrayHandlePointer = this->NewInstance(); + return newContainer; +} + +} // namespace detail + +VTKM_CONT bool UnknownArrayHandle::IsValueTypeImpl(std::type_index type) const +{ + if (!this->Container) + { + return false; + } + + // Needs optimization based on platform. OSX cannot compare typeid across translation units? + return this->Container->ValueType == type; +} + +VTKM_CONT bool UnknownArrayHandle::IsStorageTypeImpl(std::type_index type) const +{ + if (!this->Container) + { + return false; + } + + // Needs optimization based on platform. OSX cannot compare typeid across translation units? + return this->Container->StorageType == type; +} + +namespace detail +{ + +VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHandle& ref, + const std::type_info& type) +{ + std::ostringstream out; + out << "Could not find appropriate cast for array in CastAndCall.\n" + "Array: "; + ref.PrintSummary(out); + out << "TypeList: " << type.name() << "\n"; + throw vtkm::cont::ErrorBadValue(out.str()); +} + +} // namespace detail +} +} // namespace vtkm::cont diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h new file mode 100644 index 000000000..7d4fcefa4 --- /dev/null +++ b/vtkm/cont/UnknownArrayHandle.h @@ -0,0 +1,540 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#ifndef vtk_m_cont_UnknownArrayHandle_h +#define vtk_m_cont_UnknownArrayHandle_h + +#include + +#include +#include +#include + +#include + +#include +#include + +namespace vtkm +{ +namespace cont +{ + +namespace detail +{ + +template +static void UnknownAHDelete(void* mem) +{ + using AH = vtkm::cont::ArrayHandle; + AH* arrayHandle = reinterpret_cast(mem); + delete arrayHandle; +} + +template +static void* UnknownADNewInstance() +{ + return new vtkm::cont::ArrayHandle; +} + +template +static vtkm::Id UnknownAHNumberOfValues(void* mem) +{ + using AH = vtkm::cont::ArrayHandle; + AH* arrayHandle = reinterpret_cast(mem); + return arrayHandle->GetNumberOfValues(); +} + +template +static vtkm::IdComponent UnknownAHNumberOfComponents() +{ + return vtkm::VecTraits::NUM_COMPONENTS; +} + +template +static void UnknownAHReleaseResources(void* mem) +{ + using AH = vtkm::cont::ArrayHandle; + AH* arrayHandle = reinterpret_cast(mem); + arrayHandle->ReleaseResources(); +} + +template +static void UnknownAHReleaseResourcesExecution(void* mem) +{ + using AH = vtkm::cont::ArrayHandle; + AH* arrayHandle = reinterpret_cast(mem); + arrayHandle->ReleaseResourcesExecution(); +} + +template +static void UnknownAHPrintSummary(void* mem, std::ostream& out, bool full) +{ + using AH = vtkm::cont::ArrayHandle; + AH* arrayHandle = reinterpret_cast(mem); + vtkm::cont::printSummary_ArrayHandle(*arrayHandle, out, full); +} + +struct VTKM_CONT_EXPORT UnknownAHContainer; + +struct MakeUnknownAHContainerFunctor +{ + template + std::shared_ptr operator()(const vtkm::cont::ArrayHandle& array) const; +}; + +struct VTKM_CONT_EXPORT UnknownAHContainer +{ + void* ArrayHandlePointer; + + std::type_index ValueType; + std::type_index StorageType; + + using DeleteType = void(void*); + DeleteType* DeleteFunction; + + using NewInstanceType = void*(); + NewInstanceType& NewInstance; + + using NumberOfValuesType = vtkm::Id(void*); + NumberOfValuesType* NumberOfValues; + + using NumberOfComponentsType = vtkm::IdComponent(); + NumberOfComponentsType* NumberOfComponents; + + using ReleaseResourcesType = void(void*); + ReleaseResourcesType* ReleaseResources; + ReleaseResourcesType* ReleaseResourcesExecution; + + using PrintSummaryType = void(void*, std::ostream&, bool); + PrintSummaryType* PrintSummary; + + void operator=(const UnknownAHContainer&) = delete; + + ~UnknownAHContainer() { this->DeleteFunction(this->ArrayHandlePointer); } + + std::shared_ptr MakeNewInstance() const; + + template + static std::shared_ptr Make(const vtkm::cont::ArrayHandle& array) + { + return std::shared_ptr(new UnknownAHContainer(array)); + } + + template + static std::shared_ptr Make( + const vtkm::cont::ArrayHandle>& array) + { + return Make(array.GetStorage().GetArray()); + } + + template + static std::shared_ptr Make( + const vtkm::cont::ArrayHandle>& array) + { + auto&& variant = array.GetStorage().GetArrayHandleVariant(); + if (variant.IsValid()) + { + return variant.CastAndCall(MakeUnknownAHContainerFunctor{}); + } + else + { + return std::shared_ptr{}; + } + } + +private: + UnknownAHContainer(const UnknownAHContainer&) = default; + + template + explicit UnknownAHContainer(const vtkm::cont::ArrayHandle& array) + : ArrayHandlePointer(new vtkm::cont::ArrayHandle(array)) + , ValueType(typeid(T)) + , StorageType(typeid(S)) + , DeleteFunction(detail::UnknownAHDelete) + , NewInstance(detail::UnknownADNewInstance) + , NumberOfValues(detail::UnknownAHNumberOfValues) + , NumberOfComponents(detail::UnknownAHNumberOfComponents) + , ReleaseResources(detail::UnknownAHReleaseResources) + , ReleaseResourcesExecution(detail::UnknownAHReleaseResourcesExecution) + , PrintSummary(detail::UnknownAHPrintSummary) + { + } +}; + +template +inline std::shared_ptr MakeUnknownAHContainerFunctor::operator()( + const vtkm::cont::ArrayHandle& array) const +{ + return UnknownAHContainer::Make(array); +}; + +} // namespace detail + +/// \brief An ArrayHandle of an unknown type and storage. +/// +/// `UnknownArrayHandle` holds an `ArrayHandle` object using runtime polymorphism +/// to manage different value types and storage rather than compile-time templates. +/// This adds a programming convenience that helps avoid a proliferation of +/// templates. It also provides the management necessary to interface VTK-m with +/// data sources where types will not be known until runtime and is the storage +/// mechanism for classes like `DataSet` and `Field` that can hold numerous +/// types. +/// +/// To interface between the runtime polymorphism and the templated algorithms +/// in VTK-m, `UnknownArrayHandle` contains a method named `CastAndCallForTypes` +/// that determines the correct type from some known list of value types and +/// storage. This mechanism is used internally by VTK-m's worklet invocation +/// mechanism to determine the type when running algorithms. +/// +/// If the `UnknownArrayHandle` is used in a context where the possible array +/// types can be whittled down to a finite list (or you have to), you can +/// specify lists of value types and storage using the `ResetTypesAndStorage` +/// method. This will convert this object to an `UncertainArrayHandle` of the +/// given types. In cases where a finite set of types need to specified but +/// there is no known subset, `VTKM_DEFAULT_TYPE_LIST` and +/// `VTKM_DEFAULT_STORAGE_LIST` can be used. +/// +/// `ArrayHandleCast` and `ArrayHandleMultiplexer` are treated special. If +/// the `UnknownArrayHandle` is set to an `ArrayHandle` of one of these +/// types, it will actually store the `ArrayHandle` contained. Likewise, +/// if the `ArrayHandle` is retrieved as one of these types, it will +/// automatically convert it if possible. +/// +class VTKM_CONT_EXPORT UnknownArrayHandle +{ + std::shared_ptr Container; + + VTKM_CONT bool IsValueTypeImpl(std::type_index type) const; + VTKM_CONT bool IsStorageTypeImpl(std::type_index type) const; + +public: + VTKM_CONT UnknownArrayHandle() = default; + + template + VTKM_CONT UnknownArrayHandle(const vtkm::cont::ArrayHandle& array) + : Container(detail::UnknownAHContainer::Make(array)) + { + } + + /// \brief Create a new array of the same type as this array. + /// + /// This method creates a new array that is the same type as this one and + /// returns a new variant array handle for it. This method is convenient when + /// creating output arrays that should be the same type as some input array. + /// + VTKM_CONT UnknownArrayHandle NewInstance() const + { + UnknownArrayHandle newArray; + newArray.Container = this->Container->MakeNewInstance(); + return newArray; + } + + /// Returns true if this array matches the ValueType template argument. + /// + template + VTKM_CONT bool IsValueType() const + { + return this->IsValueTypeImpl(typeid(ValueType)); + } + + /// Returns true if this array matches the StorageType template argument. + /// + template + VTKM_CONT bool IsStorageType() const + { + return this->IsStorageTypeImpl(typeid(StorageType)); + } + + /// Returns true if this array matches the ArrayHandleType template argument. + /// + template + VTKM_CONT bool IsType() const + { + VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + return (this->IsValueType() && + this->IsStorageType()); + } + + /// \brief Returns the number of values in the array. + /// + VTKM_CONT vtkm::Id GetNumberOfValues() const + { + return this->Container->NumberOfValues(this->Container->ArrayHandlePointer); + } + + /// \brief Returns the number of components for each value in the array. + /// + /// If the array holds `vtkm::Vec` objects, this will return the number of components + /// in each value. If the array holds a basic C type (such as `float`), this will return 1. + /// + VTKM_CONT vtkm::IdComponent GetNumberOfComponents() const + { + return this->Container->NumberOfComponents(); + } + + /// \brief Determine if the contained array can be passed to the given array type. + /// + /// This method will return true if calling `AsArrayHandle` of the given type will + /// succeed. The result is similar to `IsType`, and if `IsType` returns true, then + /// this will return true. However, this method will also return true for other + /// types such as an `ArrayHandleMultiplexer` that can contain the array. + /// + template + VTKM_CONT bool CanConvert() const; + + ///@{ + /// Returns this array cast appropriately and stored in the given `ArrayHandle` type. + /// Throws an `ErrorBadType` if the stored array cannot be stored in the given array type. + /// Use the `IsType` method to determine if the array can be returned with the given type. + /// + template + VTKM_CONT void AsArrayHandle(vtkm::cont::ArrayHandle& array) const + { + using ArrayType = vtkm::cont::ArrayHandle; + if (!this->IsType()) + { + VTKM_LOG_CAST_FAIL(*this, decltype(array)); + throwFailedDynamicCast(vtkm::cont::TypeToString(*this), vtkm::cont::TypeToString(array)); + } + + array = *reinterpret_cast(this->Container->ArrayHandlePointer); + } + + template + VTKM_CONT void AsArrayHandle( + vtkm::cont::ArrayHandle>& array) const; + + template + VTKM_CONT void AsArrayHandle( + vtkm::cont::ArrayHandle>& array) const + { + using ContainedArrayType = vtkm::cont::ArrayHandle; + array = vtkm::cont::ArrayHandleCast( + this->AsArrayHandle()); + } + + template + VTKM_CONT ArrayType AsArrayHandle() const + { + VTKM_IS_ARRAY_HANDLE(ArrayType); + ArrayType array; + this->AsArrayHandle(array); + return array; + } + ///@} + + /// \brief Call a functor using the underlying array type. + /// + /// `CastAndCall` attempts to cast the held array to a specific value type, + /// and then calls the given functor with the cast array. You must specify + /// the `TypeList` and `StorageList` as template arguments. + /// + template + VTKM_CONT void CastAndCallForTypes(Functor&& functor, Args&&... args) const; + + /// Releases any resources being used in the execution environment (that are + /// not being shared by the control environment). + /// + VTKM_CONT void ReleaseResourcesExecution() const + { + return this->Container->ReleaseResourcesExecution(this->Container->ArrayHandlePointer); + } + + /// Releases all resources in both the control and execution environments. + /// + VTKM_CONT void ReleaseResources() const + { + return this->Container->ReleaseResources(this->Container->ArrayHandlePointer); + } + + VTKM_CONT void PrintSummary(std::ostream& out, bool full = false) const + { + this->Container->PrintSummary(this->Container->ArrayHandlePointer, out, full); + } +}; + +//============================================================================= +// Out of class implementations + +namespace detail +{ + +template +struct UnknownArrayHandleCanConvert +{ + VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const + { + return array.IsType>(); + } +}; + +template +struct UnknownArrayHandleCanConvert> +{ + VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const + { + return UnknownArrayHandleCanConvert{}(array); + } +}; + +template +struct UnknownArrayHandleCanConvertTry +{ + template + VTKM_CONT void operator()(S, const vtkm::cont::UnknownArrayHandle& array, bool& canConvert) const + { + canConvert |= UnknownArrayHandleCanConvert{}(array); + } +}; + +template +struct UnknownArrayHandleCanConvert> +{ + VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const + { + bool canConvert = false; + vtkm::ListForEach(UnknownArrayHandleCanConvertTry{}, vtkm::List{}, array, canConvert); + return canConvert; + } +}; + +} // namespace detail + +template +VTKM_CONT bool UnknownArrayHandle::CanConvert() const +{ + VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + + return detail::UnknownArrayHandleCanConvert{}(*this); +} + +namespace detail +{ + +struct UnknownArrayHandleMultplexerCastTry +{ + template + VTKM_CONT void operator()( + S, + const vtkm::cont::UnknownArrayHandle& unknownArray, + vtkm::cont::ArrayHandle>& outputArray, + bool& converted) const + { + using ArrayType = vtkm::cont::ArrayHandle; + if (!converted && unknownArray.CanConvert()) + { + outputArray.GetStorage().SetArray(unknownArray.AsArrayHandle()); + converted = true; + } + } +}; + +} // namespace detail + +template +void UnknownArrayHandle::AsArrayHandle( + vtkm::cont::ArrayHandle>& array) const +{ + bool converted = false; + vtkm::ListForEach( + detail::UnknownArrayHandleMultplexerCastTry{}, vtkm::List{}, *this, array, converted); + + if (!converted) + { + VTKM_LOG_CAST_FAIL(*this, decltype(array)); + throwFailedDynamicCast(vtkm::cont::TypeToString(*this), vtkm::cont::TypeToString(array)); + } +} + +namespace detail +{ + +struct UnknownArrayHandleTry +{ + template + void operator()(vtkm::List, + Functor&& f, + bool& called, + const vtkm::cont::UnknownArrayHandle& unknownArray, + Args&&... args) const + { + using DerivedArrayType = vtkm::cont::ArrayHandle; + if (!called && unknownArray.IsType()) + { + called = true; + DerivedArrayType derivedArray; + unknownArray.AsArrayHandle(derivedArray); + VTKM_LOG_CAST_SUCC(unknownArray, derivedArray); + + // If you get a compile error here, it means that you have called CastAndCall for a + // vtkm::cont::UnknownArrayHandle and the arguments of the functor do not match those + // being passed. This is often because it is calling the functor with an ArrayHandle + // type that was not expected. Either add overloads to the functor to accept all + // possible array types or constrain the types tried for the CastAndCall. Note that + // the functor will be called with an array of type vtkm::cont::ArrayHandle. + // Directly using a subclass of ArrayHandle (e.g. vtkm::cont::ArrayHandleConstant) + // might not work. + f(derivedArray, std::forward(args)...); + } + } +}; + +template +struct IsUndefinedArrayType +{ +}; +template +struct IsUndefinedArrayType> : vtkm::cont::internal::IsInvalidArrayHandle +{ +}; + +template +using ListAllArrayTypes = + vtkm::ListRemoveIf, IsUndefinedArrayType>; + + +VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHandle&, + const std::type_info&); + +} // namespace detail + + + +template +VTKM_CONT void UnknownArrayHandle::CastAndCallForTypes(Functor&& f, Args&&... args) const +{ + using crossProduct = detail::ListAllArrayTypes; + + bool called = false; + vtkm::ListForEach(detail::UnknownArrayHandleTry{}, + crossProduct{}, + std::forward(f), + called, + *this, + std::forward(args)...); + if (!called) + { + // throw an exception + VTKM_LOG_CAST_FAIL(*this, TypeList); + detail::ThrowCastAndCallException(*this, typeid(TypeList)); + } +} + +template +void CastAndCall(const UnknownArrayHandle& handle, Functor&& f, Args&&... args) +{ + handle.CastAndCallForTypes( + std::forward(f), std::forward(args)...); +} +} +} // namespace vtkm::cont + +#endif //vtk_m_cont_UnknownArrayHandle_h diff --git a/vtkm/cont/testing/CMakeLists.txt b/vtkm/cont/testing/CMakeLists.txt index 163753ce4..e5a9718b9 100644 --- a/vtkm/cont/testing/CMakeLists.txt +++ b/vtkm/cont/testing/CMakeLists.txt @@ -88,6 +88,7 @@ set(unit_tests UnitTestTimer.cxx UnitTestToken.cxx UnitTestTryExecute.cxx + UnitTestUnknownArrayHandle.cxx UnitTestVariantArrayHandle.cxx ) diff --git a/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx new file mode 100644 index 000000000..7bfe18137 --- /dev/null +++ b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx @@ -0,0 +1,398 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ + +#include + +#include + +#include + +namespace +{ + +// Make an "unusual" type to use in the test. This is simply a type that +// is sure not to be declared elsewhere. +struct UnusualType +{ + using T = vtkm::Id; + T X; + UnusualType() = default; + UnusualType(T x) + : X(x) + { + } + UnusualType& operator=(T x) + { + this->X = x; + return *this; + } + operator T() const { return this->X; } +}; + +} // anonymous namespace + +namespace vtkm +{ + +// UnknownArrayHandle requires its value type to have a defined VecTraits +// class. One of the tests is to use an "unusual" array. +// Make an implementation here. Because I am lazy, this is only a partial +// implementation. +template <> +struct VecTraits : VecTraits +{ +}; + +} // namespace vtkm + +namespace +{ + +const vtkm::Id ARRAY_SIZE = 10; + +struct CheckFunctor +{ + template + static void CheckArray(const vtkm::cont::ArrayHandle& array) + { + VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size."); + CheckPortal(array.ReadPortal()); + } + + template + static void CheckArray(const vtkm::cont::ArrayHandle& array) + { + VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size."); + auto portal = array.ReadPortal(); + for (vtkm::Id index = 0; index < array.GetNumberOfValues(); ++index) + { + VTKM_TEST_ASSERT(portal.Get(index) == TestValue(index, UnusualType::T{})); + } + } + + template + void operator()(const vtkm::cont::ArrayHandle& array, bool& called) const + { + called = true; + std::cout << " Checking for array type " << typeid(T).name() << " with storage " + << typeid(S).name() << std::endl; + + CheckArray(array); + } +}; + +void BasicUnknownArrayChecks(const vtkm::cont::UnknownArrayHandle& array, + vtkm::IdComponent numComponents) +{ + VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, + "Dynamic array reports unexpected size."); + VTKM_TEST_ASSERT(array.GetNumberOfComponents() == numComponents, + "Dynamic array reports unexpected number of components."); +} + +void CheckUnknownArrayDefaults(const vtkm::cont::UnknownArrayHandle& array, + vtkm::IdComponent numComponents) +{ + BasicUnknownArrayChecks(array, numComponents); + + std::cout << " CastAndCall with default types" << std::endl; + bool called = false; + CastAndCall(array, CheckFunctor(), called); +} + +template +void CheckUnknownArray(const vtkm::cont::UnknownArrayHandle& array, vtkm::IdComponent numComponents) +{ + VTKM_IS_LIST(TypeList); + VTKM_IS_LIST(StorageList); + + BasicUnknownArrayChecks(array, numComponents); + + std::cout << " CastAndCall with given types" << std::endl; + bool called = false; + array.CastAndCallForTypes(CheckFunctor{}, called); + + VTKM_TEST_ASSERT( + called, "The functor was never called (and apparently a bad value exception not thrown)."); +} + +template +vtkm::cont::ArrayHandle CreateArray(T) +{ + vtkm::cont::ArrayHandle array; + array.Allocate(ARRAY_SIZE); + SetPortal(array.WritePortal()); + return array; +} + +vtkm::cont::ArrayHandle CreateArray(UnusualType) +{ + vtkm::cont::ArrayHandle array; + array.Allocate(ARRAY_SIZE); + auto portal = array.WritePortal(); + for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index) + { + portal.Set(index, TestValue(index, UnusualType::T{})); + } + return array; +} + +template +vtkm::cont::UnknownArrayHandle CreateArrayUnknown(T t) +{ + return vtkm::cont::UnknownArrayHandle(CreateArray(t)); +} + +template +void CheckCastToArrayHandle(const ArrayHandleType& array) +{ + VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + + vtkm::cont::UnknownArrayHandle arrayUnknown = array; + VTKM_TEST_ASSERT(!arrayUnknown.IsType>(), + "Dynamic array reporting is wrong type."); + + ArrayHandleType castArray1; + arrayUnknown.AsArrayHandle(castArray1); + VTKM_TEST_ASSERT(arrayUnknown.CanConvert(), "Did not query handle correctly."); + VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array."); + + ArrayHandleType castArray2 = arrayUnknown.AsArrayHandle(); + VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array."); + + vtkm::cont::UnknownArrayHandle arrayUnknown2 = vtkm::cont::ArrayHandleMultiplexer< + ArrayHandleType, + vtkm::cont::ArrayHandleConstant>(array); + VTKM_TEST_ASSERT(arrayUnknown2.IsType(), + "Putting in multiplexer did not pull out array."); +} + +// A vtkm::Vec if NumComps > 1, otherwise a scalar +template +using VecOrScalar = typename std::conditional<(NumComps > 1), vtkm::Vec, T>::type; + +template +void TryNewInstance(vtkm::cont::UnknownArrayHandle originalArray) +{ + // This check should already have been performed by caller, but just in case. + CheckUnknownArray, VTKM_DEFAULT_STORAGE_LIST>(originalArray, + vtkm::VecTraits::NUM_COMPONENTS); + + std::cout << "Create new instance of array." << std::endl; + vtkm::cont::UnknownArrayHandle newArray = originalArray.NewInstance(); + + std::cout << "Get a static instance of the new array (which checks the type)." << std::endl; + vtkm::cont::ArrayHandle staticArray; + newArray.AsArrayHandle(staticArray); + + std::cout << "Fill the new array with invalid values and make sure the original" << std::endl + << "is uneffected." << std::endl; + staticArray.Allocate(ARRAY_SIZE); + for (vtkm::Id index = 0; index < ARRAY_SIZE; index++) + { + staticArray.WritePortal().Set(index, TestValue(index + 100, T())); + } + CheckUnknownArray, VTKM_DEFAULT_STORAGE_LIST>(originalArray, + vtkm::VecTraits::NUM_COMPONENTS); + + std::cout << "Set the new static array to expected values and make sure the new" << std::endl + << "dynamic array points to the same new values." << std::endl; + for (vtkm::Id index = 0; index < ARRAY_SIZE; index++) + { + staticArray.WritePortal().Set(index, TestValue(index, T())); + } + CheckUnknownArray, VTKM_DEFAULT_STORAGE_LIST>(newArray, + vtkm::VecTraits::NUM_COMPONENTS); +} + +template +void TryAsMultiplexer(vtkm::cont::UnknownArrayHandle sourceArray) +{ + auto originalArray = sourceArray.AsArrayHandle>(); + + { + std::cout << "Get multiplex array through direct type." << std::endl; + using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer, + vtkm::cont::ArrayHandleConstant>; + VTKM_TEST_ASSERT(sourceArray.CanConvert()); + MultiplexerType multiplexArray = sourceArray.AsArrayHandle(); + + VTKM_TEST_ASSERT(multiplexArray.IsValid()); + VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal())); + } + + { + std::cout << "Get multiplex array through cast type." << std::endl; + using CastT = typename vtkm::VecTraits::template ReplaceBaseComponentType; + using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandleCast>>; + VTKM_TEST_ASSERT(sourceArray.CanConvert()); + MultiplexerType multiplexArray = sourceArray.AsArrayHandle(); + + VTKM_TEST_ASSERT(multiplexArray.IsValid()); + VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal())); + } + +#if 0 + // Maybe we should support this, but right now we don't + { + std::cout << "Make sure multiplex array prefers direct array (1st arg)" << std::endl; + using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer< + vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandleCast>>; + MultiplexerType multiplexArray = sourceArray.AsArrayHandle(); + + VTKM_TEST_ASSERT(multiplexArray.IsValid()); + VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 0); + VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal())); + } + + { + std::cout << "Make sure multiplex array prefers direct array (2nd arg)" << std::endl; + using MultiplexerType = + vtkm::cont::ArrayHandleMultiplexer>, + vtkm::cont::ArrayHandle>; + MultiplexerType multiplexArray = sourceArray.AsArrayHandle(); + + VTKM_TEST_ASSERT(multiplexArray.IsValid()); + VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 1); + VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), originalArray.ReadPortal())); + } +#endif +} + +template +void TryDefaultType() +{ + vtkm::cont::UnknownArrayHandle array = CreateArrayUnknown(T{}); + + CheckUnknownArrayDefaults(array, vtkm::VecTraits::NUM_COMPONENTS); + + TryNewInstance(array); + + TryAsMultiplexer(array); +} + +struct TryBasicVTKmType +{ + template + void operator()(T) const + { + vtkm::cont::UnknownArrayHandle array = CreateArrayUnknown(T()); + + CheckUnknownArray( + array, vtkm::VecTraits::NUM_COMPONENTS); + + TryNewInstance(array); + } +}; + +void TryUnusualType() +{ + // A string is an unlikely type to be declared elsewhere in VTK-m. + vtkm::cont::UnknownArrayHandle array = CreateArrayUnknown(UnusualType{}); + + try + { + CheckUnknownArray(array, 1); + VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type."); + } + catch (vtkm::cont::ErrorBadValue&) + { + std::cout << " Caught exception for unrecognized type." << std::endl; + } + CheckUnknownArray, VTKM_DEFAULT_STORAGE_LIST>(array, 1); + std::cout << " Found type when type list was reset." << std::endl; +} + +template +void TryCastToArrayHandle(const ArrayHandleType& array) +{ + CheckCastToArrayHandle(array); +} + +void TryCastToArrayHandle() +{ + std::cout << " Normal array handle." << std::endl; + vtkm::Id buffer[ARRAY_SIZE]; + for (vtkm::Id index = 0; index < ARRAY_SIZE; index++) + { + buffer[index] = TestValue(index, vtkm::Id()); + } + + vtkm::cont::ArrayHandle array = + vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE, vtkm::CopyFlag::On); + TryCastToArrayHandle(array); + + std::cout << " Constant array handle." << std::endl; + TryCastToArrayHandle(vtkm::cont::make_ArrayHandleConstant(5, ARRAY_SIZE)); +} + +void TrySetCastArray() +{ + vtkm::cont::ArrayHandle knownArray = CreateArray(vtkm::Id{}); + vtkm::cont::UnknownArrayHandle unknownArray( + vtkm::cont::make_ArrayHandleCast(knownArray)); + + // The unknownArray should actually hold the original knownArray type even though we gave it + // a cast array. + CheckUnknownArray, vtkm::List>(unknownArray, 1); +} + +void TrySetMultiplexerArray() +{ + vtkm::cont::ArrayHandle knownArray = CreateArray(vtkm::Id{}); + vtkm::cont::ArrayHandleMultiplexer, + vtkm::cont::ArrayHandleConstant> + multiplexerArray(knownArray); + vtkm::cont::UnknownArrayHandle unknownArray(multiplexerArray); + + // The unknownArray should actually hold the original knownArray type even though we gave it + // a multiplexer array. + CheckUnknownArray, vtkm::List>(unknownArray, 1); +} + +struct DefaultTypeFunctor +{ + template + void operator()(T) const + { + TryDefaultType(); + } +}; + +void TestUnknownArrayHandle() +{ + std::cout << "Try common types with default type lists." << std::endl; + vtkm::testing::Testing::TryTypes(DefaultTypeFunctor{}, VTKM_DEFAULT_TYPE_LIST{}); + + std::cout << "Try exemplar VTK-m types." << std::endl; + vtkm::testing::Testing::TryTypes(TryBasicVTKmType{}); + + std::cout << "Try unusual type." << std::endl; + TryUnusualType(); + + std::cout << "Try CastToArrayHandle" << std::endl; + TryCastToArrayHandle(); + + std::cout << "Try setting ArrayHandleCast" << std::endl; + TrySetCastArray(); + + std::cout << "Try setting ArrayHandleMultiplexer" << std::endl; + TrySetMultiplexerArray(); +} + +} // anonymous namespace + +int UnitTestUnknownArrayHandle(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(TestUnknownArrayHandle, argc, argv); +} From 94aa6449b951c487be5caf4517cd2eac68dde815 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 5 Aug 2020 06:42:33 -0600 Subject: [PATCH 02/51] Add UncertainArrayHandle --- docs/changelog/unknown-array-handle.md | 109 ++++++++++++++++ vtkm/cont/CMakeLists.txt | 1 + vtkm/cont/UncertainArrayHandle.h | 122 ++++++++++++++++++ vtkm/cont/UnknownArrayHandle.h | 65 ++++++++-- .../testing/UnitTestUnknownArrayHandle.cxx | 8 +- 5 files changed, 295 insertions(+), 10 deletions(-) create mode 100644 docs/changelog/unknown-array-handle.md create mode 100644 vtkm/cont/UncertainArrayHandle.h diff --git a/docs/changelog/unknown-array-handle.md b/docs/changelog/unknown-array-handle.md new file mode 100644 index 000000000..90b375c64 --- /dev/null +++ b/docs/changelog/unknown-array-handle.md @@ -0,0 +1,109 @@ +# UnknownArrayHandle and UncertainArrayHandle for runtime-determined types + +Two new classes have been added to VTK-m: `UnknownArrayHandle` and +`UncertainArrayHandle`. These classes serve the same purpose as the set of +`VariantArrayHandle` classes and will replace them. + +Motivated mostly by the desire to move away from `ArrayHandleVirtual`, we +have multiple reasons to completely refactor the `VariantArrayHandle` +class. These include changing the implementation, some behavior, and even +the name. + +## Motivation + +We have several reasons that have accumulated to revisit the implementation +of `VariantArrayHandle`. + +### Move away from `ArrayHandleVirtual` + +The current implementation of `VariantArrayHandle` internally stores the +array wrapped in an `ArrayHandleVirtual`. That makes sense since you might +as well consolidate the hierarchy of virtual objects into one. + +Except `ArrayHandleVirtual` is being deprecated, so it no longer makes +sense to use that internally. + +So we will transition the class back to managing the data as typeless on +its own. We will consider using function pointers rather than actual +virtual functions because compilers can be slow in creating lots of virtual +subclasses. + +### Reintroduce storage tag lists + +The original implementation of `VariantArrayHandle` (which at the time was +called `DynamicArrayHandle`) actually had two type lists: one for the array +value type and one for the storage type. The storage type list was removed +soon after `ArrayHandleVirtual` was introduced because whatever the type of +array it could be access as `ArrayHandleVirtual`. + +However, with `ArrayHandleVirtual` being deprecated, this feature is no +longer possible. We are in need again for the list of storage types to try. +Thus, we need to reintroduce this template argument to +`VariantArrayHandle`. + +### More clear name + +The name of this class has always been unsatisfactory. The first name, +`DynamicArrayHandle`, makes it sound like the data is always changing. The +second name, `VariantArrayHandle`, makes it sound like an array that holds +a value type that can vary (like an `std::variant`). + +We can use a more clear name that expresses better that it is holding an +`ArrayHandle` of an _unknown_ type. + +### Take advantage of default types for less templating + +Once upon a time everything in VTK-m was templated header library. Things +have changed quite a bit since then. The most recent development is the +ability to select the "default types" with CMake configuration that allows +you to select a global set of types you care about during compilation. This +is so units like filters can be compiled into a library with all types we +care about, and we don't have to constantly recompile units. + +This means that we are becoming less concerned about maintaining type lists +everywhere. Often we can drop the type list and pass data across libraries. + +With that in mind, it makes less sense for `VariantArrayHandle` to actually +be a `using` alias for `VariantArrayHandleBase`. + +In response, we can revert the is-a relationship between the two. Have a +completely typeless version as the base class and have a second version +templated version to express when the type of the array has been partially +narrowed down to given type lists. + +## New Name and Structure + +The ultimate purpose of this class is to store an `ArrayHandle` where the +value and storage types are unknown. Thus, an appropriate name for the +class is `UnknownArrayHandle`. + +`UnknownArrayHandle` is _not_ templated. It simply stores an `ArrayHandle` +in a typeless (`void *`) buffer. It does, however, contain many templated +methods that allow you to query whether the contained array matches given +types, to cast to given types, and to cast and call to a given functor +(from either given type lists or default lists). + +Rather than have a virtual class structure to manage the typeless array, +the new management will use function pointers. This has shown to sometimes +improve compile times and generate less code. + +Sometimes it is the case that the set of potential types can be narrowed. In +this case, the array ceases to be unknown and becomes _uncertain_. Thus, +the companion class to `UnknownArrayHandle` is `UncertainArrayHandle`. + +`UncertainArrayHandle` has two template parameters: a list of potential +value types and a list of potential storage types. The behavior of +`UncertainArrayHandle` matches that of `UnknownArrayHandle` (and might +inherit from it). However, for `CastAndCall` operations, it will use the +type lists defined in its template parameters. + +## Serializing UnknownArrayHandle + +Because `UnknownArrayHandle` is not templated, it contains some +opportunities to compile things into the `vtkm_cont` library. Templated +methods like `CastAndCall` cannot be, but the specializations of DIY's +serialize can be. + +And since it only has to be compiled once into a library, we can spend some +extra time compiling for more types. We don't have to restrict ourselves to +`VTKM_DEFAULT_TYPE_LIST`. We can compile for vtkm::TypeListTagAll. diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index 3c6f852ef..46707847a 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -116,6 +116,7 @@ set(headers Token.h TryExecute.h SerializableTypeString.h + UncertainArrayHandle.h UnknownArrayHandle.h VariantArrayHandle.h VirtualObjectHandle.h diff --git a/vtkm/cont/UncertainArrayHandle.h b/vtkm/cont/UncertainArrayHandle.h new file mode 100644 index 000000000..1d1132629 --- /dev/null +++ b/vtkm/cont/UncertainArrayHandle.h @@ -0,0 +1,122 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#ifndef vtk_m_cont_UncertainArrayHandle_h +#define vtk_m_cont_UncertainArrayHandle_h + +#include + +namespace vtkm +{ +namespace cont +{ + +/// \brief An ArrayHandle of an uncertain value type and storage. +/// +/// `UncertainArrayHandle` holds an `ArrayHandle` object using runtime polymorphism +/// to manage different value and storage types. It behaves like its superclass, +/// `UnknownArrayHandle`, except that it also contains two template parameters that +/// provide `vtkm::List`s of potential value and storage types, respectively. +/// +/// These potential value and storage types come into play when the `CastAndCall` +/// method is called (or the `UncertainArrayHandle` is used in the +/// `vtkm::cont::CastAndCall` function). In this case, the `CastAndCall` will +/// search for `ArrayHandle`s of types that match these two lists. +/// +/// Both `UncertainArrayHandle` and `UnknownArrayHandle` have a method named +/// `ResetTypes` that redefine the lists of potential value and storage types +/// by returning a new `UncertainArrayHandle` containing the same `ArrayHandle` +/// but with the new value and storage type lists. +/// +template +class VTKM_ALWAYS_EXPORT UncertainArrayHandle : public vtkm::cont::UnknownArrayHandle +{ + VTKM_IS_LIST(ValueTypeList); + VTKM_IS_LIST(StorageTypeList); + + VTKM_STATIC_ASSERT_MSG((!std::is_same::value), + "Cannot use vtkm::ListUniversal with UncertainArrayHandle."); + VTKM_STATIC_ASSERT_MSG((!std::is_same::value), + "Cannot use vtkm::ListUniversal with UncertainArrayHandle."); + + using Superclass = UnknownArrayHandle; + using Thisclass = UncertainArrayHandle; + +public: + VTKM_CONT UncertainArrayHandle() = default; + + template + VTKM_CONT UncertainArrayHandle(const vtkm::cont::ArrayHandle& array) + : Superclass(array) + { + } + + explicit VTKM_CONT UncertainArrayHandle(const vtkm::cont::UnknownArrayHandle& src) + : Superclass(src) + { + } + + UncertainArrayHandle(const Thisclass&) = default; + + template + VTKM_CONT UncertainArrayHandle(const UncertainArrayHandle& src) + : Superclass(src) + { + } + + /// \brief Create a new array of the same type as this array. + /// + /// This method creates a new array that is the same type as this one and + /// returns a new `UncertainArrayHandle` for it. This method is convenient when + /// creating output arrays that should be the same type as some input array. + /// + VTKM_CONT Thisclass NewInstance() const { return Thisclass(this->Superclass::NewInstance()); } + + /// Like `ResetTypes` except it only resets the value types. + /// + template + VTKM_CONT UncertainArrayHandle ResetValueTypes( + NewValueTypeList = NewValueTypeList{}) const + { + return this->ResetTypes(); + } + + /// Like `ResetTypes` except it only resets the storage types. + /// + template + VTKM_CONT UncertainArrayHandle ResetStorageTypes( + NewStorageTypeList = NewStorageTypeList{}) const + { + return this->ResetTypes(); + } + + /// \brief Call a functor using the underlying array type. + /// + /// `CastAndCall` attempts to cast the held array to a specific value type, + /// and then calls the given functor with the cast array. + /// + template + VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const + { + this->CastAndCallForTypes(std::forward(functor), + std::forward(args)...); + } +}; + +// Defined here to avoid circular dependencies between UnknownArrayHandle and UncertainArrayHandle. +template +VTKM_CONT vtkm::cont::UncertainArrayHandle + UnknownArrayHandle::ResetTypes(NewValueTypeList, NewStorageTypeList) const +{ + return vtkm::cont::UncertainArrayHandle(*this); +} +} +} + +#endif //vtk_m_cont_UncertainArrayHandle_h diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index 7d4fcefa4..fb1d0f151 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -177,10 +177,14 @@ inline std::shared_ptr MakeUnknownAHContainerFunctor::operat } // namespace detail -/// \brief An ArrayHandle of an unknown type and storage. +// Forward declaration. Include UncertainArrayHandle.h if using this. +template +class UncertainArrayHandle; + +/// \brief An ArrayHandle of an unknown value type and storage. /// /// `UnknownArrayHandle` holds an `ArrayHandle` object using runtime polymorphism -/// to manage different value types and storage rather than compile-time templates. +/// to manage different value and storage types rather than compile-time templates. /// This adds a programming convenience that helps avoid a proliferation of /// templates. It also provides the management necessary to interface VTK-m with /// data sources where types will not be known until runtime and is the storage @@ -226,13 +230,16 @@ public: /// \brief Create a new array of the same type as this array. /// /// This method creates a new array that is the same type as this one and - /// returns a new variant array handle for it. This method is convenient when + /// returns a new `UnknownArrayHandle` for it. This method is convenient when /// creating output arrays that should be the same type as some input array. /// VTKM_CONT UnknownArrayHandle NewInstance() const { UnknownArrayHandle newArray; - newArray.Container = this->Container->MakeNewInstance(); + if (this->Container) + { + newArray.Container = this->Container->MakeNewInstance(); + } return newArray; } @@ -262,11 +269,31 @@ public: this->IsStorageType()); } + /// \brief Assigns potential value and storage types. + /// + /// Calling this method will return an `UncertainArrayHandle` with the provided + /// value and storage type lists. The returned object will hold the same + /// `ArrayHandle`, but `CastAndCall`s on the returned object will be constrained + /// to the given types. + /// + // Defined in UncertainArrayHandle.h + template + VTKM_CONT vtkm::cont::UncertainArrayHandle ResetTypes( + NewValueTypeList = NewValueTypeList{}, + NewStorageTypeList = NewStorageTypeList{}) const; + /// \brief Returns the number of values in the array. /// VTKM_CONT vtkm::Id GetNumberOfValues() const { - return this->Container->NumberOfValues(this->Container->ArrayHandlePointer); + if (this->Container) + { + return this->Container->NumberOfValues(this->Container->ArrayHandlePointer); + } + else + { + return 0; + } } /// \brief Returns the number of components for each value in the array. @@ -276,7 +303,14 @@ public: /// VTKM_CONT vtkm::IdComponent GetNumberOfComponents() const { - return this->Container->NumberOfComponents(); + if (this->Container) + { + return this->Container->NumberOfComponents(); + } + else + { + return 0; + } } /// \brief Determine if the contained array can be passed to the given array type. @@ -344,19 +378,32 @@ public: /// VTKM_CONT void ReleaseResourcesExecution() const { - return this->Container->ReleaseResourcesExecution(this->Container->ArrayHandlePointer); + if (this->Container) + { + this->Container->ReleaseResourcesExecution(this->Container->ArrayHandlePointer); + } } /// Releases all resources in both the control and execution environments. /// VTKM_CONT void ReleaseResources() const { - return this->Container->ReleaseResources(this->Container->ArrayHandlePointer); + if (this->Container) + { + this->Container->ReleaseResources(this->Container->ArrayHandlePointer); + } } VTKM_CONT void PrintSummary(std::ostream& out, bool full = false) const { - this->Container->PrintSummary(this->Container->ArrayHandlePointer, out, full); + if (this->Container) + { + this->Container->PrintSummary(this->Container->ArrayHandlePointer, out, full); + } + else + { + out << "null array" << std::endl; + } } }; diff --git a/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx index 7bfe18137..e581581e6 100644 --- a/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx @@ -8,6 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ +#include #include #include @@ -104,7 +105,7 @@ void CheckUnknownArrayDefaults(const vtkm::cont::UnknownArrayHandle& array, std::cout << " CastAndCall with default types" << std::endl; bool called = false; - CastAndCall(array, CheckFunctor(), called); + vtkm::cont::CastAndCall(array, CheckFunctor(), called); } template @@ -118,7 +119,12 @@ void CheckUnknownArray(const vtkm::cont::UnknownArrayHandle& array, vtkm::IdComp std::cout << " CastAndCall with given types" << std::endl; bool called = false; array.CastAndCallForTypes(CheckFunctor{}, called); + VTKM_TEST_ASSERT( + called, "The functor was never called (and apparently a bad value exception not thrown)."); + std::cout << " Check CastAndCall again with UncertainArrayHandle" << std::endl; + called = false; + vtkm::cont::CastAndCall(array.ResetTypes(), CheckFunctor{}, called); VTKM_TEST_ASSERT( called, "The functor was never called (and apparently a bad value exception not thrown)."); } From fca25fa3c75416f8df77b885ffa5fce9157ff830 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 5 Aug 2020 10:01:51 -0600 Subject: [PATCH 03/51] Enable serialization of UnknownArrayHandle and UncertainArrayHandle Because UnknownArrayHandle is not typed, we can compile into vtkm_cont the ability to serialize many types. --- vtkm/cont/UncertainArrayHandle.h | 95 ++++++++ vtkm/cont/UnknownArrayHandle.cxx | 67 ++++++ vtkm/cont/UnknownArrayHandle.h | 40 +++- vtkm/cont/testing/Testing.h | 34 +++ .../UnitTestSerializationArrayHandle.cxx | 205 +++++++++++------- 5 files changed, 356 insertions(+), 85 deletions(-) diff --git a/vtkm/cont/UncertainArrayHandle.h b/vtkm/cont/UncertainArrayHandle.h index 1d1132629..05739b4ca 100644 --- a/vtkm/cont/UncertainArrayHandle.h +++ b/vtkm/cont/UncertainArrayHandle.h @@ -119,4 +119,99 @@ VTKM_CONT vtkm::cont::UncertainArrayHandle } } +//============================================================================= +// Specializations of serialization related classes +/// @cond SERIALIZATION + +namespace vtkm +{ +namespace cont +{ + +template +struct SerializableTypeString> +{ + static VTKM_CONT std::string Get() + { + return SerializableTypeString::Get(); + } +}; +} +} // namespace vtkm::cont + +namespace mangled_diy_namespace +{ + +namespace internal +{ + +struct UncertainArrayHandleSerializeFunctor +{ + template + void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const + { + vtkmdiy::save(bb, vtkm::cont::SerializableTypeString::Get()); + vtkmdiy::save(bb, ah); + } +}; + +struct UncertainArrayHandleDeserializeFunctor +{ + template + void operator()(vtkm::List, + vtkm::cont::UnknownArrayHandle& unknownArray, + const std::string& typeString, + bool& success, + BinaryBuffer& bb) const + { + using ArrayHandleType = vtkm::cont::ArrayHandle; + + if (!success && (typeString == vtkm::cont::SerializableTypeString::Get())) + { + ArrayHandleType knownArray; + vtkmdiy::load(bb, knownArray); + unknownArray = knownArray; + success = true; + } + } +}; + +} // internal + +template +struct Serialization> +{ + using Type = vtkm::cont::UncertainArrayHandle; + +public: + static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj) + { + obj.CastAndCall(internal::UncertainArrayHandleSerializeFunctor{}, bb); + } + + static VTKM_CONT void load(BinaryBuffer& bb, Type& obj) + { + std::string typeString; + vtkmdiy::load(bb, typeString); + + bool success = false; + vtkm::ListForEach(internal::UncertainArrayHandleDeserializeFunctor{}, + vtkm::cont::detail::ListAllArrayTypes{}, + obj, + typeString, + success, + bb); + + if (!success) + { + throw vtkm::cont::ErrorBadType( + "Error deserializing Unknown/UncertainArrayHandle. Message TypeString: " + typeString); + } + } +}; + +} // namespace mangled_diy_namespace + +/// @endcond SERIALIZATION + #endif //vtk_m_cont_UncertainArrayHandle_h diff --git a/vtkm/cont/UnknownArrayHandle.cxx b/vtkm/cont/UnknownArrayHandle.cxx index 63636eb94..46727a3f1 100644 --- a/vtkm/cont/UnknownArrayHandle.cxx +++ b/vtkm/cont/UnknownArrayHandle.cxx @@ -10,6 +10,37 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using UnknownSerializationTypes = vtkm::TypeListAll; +using UnknownSerializationStorage = + vtkm::ListAppend, + vtkm::cont::StorageTagConstant, + vtkm::cont::StorageTagCounting, + vtkm::cont::StorageTagIndex, + vtkm::cont::StorageTagGroupVec, + vtkm::cont::StorageTagGroupVec, + vtkm::cont::StorageTagGroupVec, + vtkm::cont::StorageTagPermutation, + vtkm::cont::StorageTagReverse, + vtkm::cont::StorageTagSOA, + vtkm::cont::StorageTagUniformPoints>>; + namespace vtkm { namespace cont @@ -69,3 +100,39 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHa } // namespace detail } } // namespace vtkm::cont + + +//============================================================================= +// Specializations of serialization related classes + +namespace vtkm +{ +namespace cont +{ + +std::string SerializableTypeString::Get() +{ + return "UnknownAH"; +} +} +} // namespace vtkm::cont + +namespace mangled_diy_namespace +{ + +void Serialization::save(BinaryBuffer& bb, + const vtkm::cont::UnknownArrayHandle& obj) +{ + vtkmdiy::save(bb, obj.ResetTypes()); +} + +void Serialization::load(BinaryBuffer& bb, + vtkm::cont::UnknownArrayHandle& obj) +{ + vtkm::cont::UncertainArrayHandle + uncertainArray; + vtkmdiy::load(bb, uncertainArray); + obj = uncertainArray; +} + +} // namespace mangled_diy_namespace diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index fb1d0f151..d797eb168 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -538,14 +538,14 @@ template struct IsUndefinedArrayType { }; -template -struct IsUndefinedArrayType> : vtkm::cont::internal::IsInvalidArrayHandle +template +struct IsUndefinedArrayType> : vtkm::cont::internal::IsInvalidArrayHandle { }; -template +template using ListAllArrayTypes = - vtkm::ListRemoveIf, IsUndefinedArrayType>; + vtkm::ListRemoveIf, IsUndefinedArrayType>; VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHandle&, @@ -584,4 +584,36 @@ void CastAndCall(const UnknownArrayHandle& handle, Functor&& f, Args&&... args) } } // namespace vtkm::cont +//============================================================================= +// Specializations of serialization related classes +/// @cond SERIALIZATION + +namespace vtkm +{ +namespace cont +{ + +template <> +struct VTKM_CONT_EXPORT SerializableTypeString +{ + static VTKM_CONT std::string Get(); +}; +} +} // namespace vtkm::cont + +namespace mangled_diy_namespace +{ + +template <> +struct VTKM_CONT_EXPORT Serialization +{ +public: + static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::UnknownArrayHandle& obj); + static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::UnknownArrayHandle& obj); +}; + +} // namespace mangled_diy_namespace + +/// @endcond SERIALIZATION + #endif //vtk_m_cont_UnknownArrayHandle_h diff --git a/vtkm/cont/testing/Testing.h b/vtkm/cont/testing/Testing.h index 666aa7bc2..958105cfa 100644 --- a/vtkm/cont/testing/Testing.h +++ b/vtkm/cont/testing/Testing.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -380,6 +381,39 @@ struct TestEqualArrayHandle { array2.CastAndCall(*this, array1, result); } + + template + VTKM_CONT void operator()(const vtkm::cont::ArrayHandle& array1, + const vtkm::cont::UnknownArrayHandle& array2, + TestEqualResult& result) const + { + array2.CastAndCallForTypes, vtkm::List>( + *this, array1, result); + } + + template + VTKM_CONT void operator()(const vtkm::cont::UnknownArrayHandle& array1, + const vtkm::cont::ArrayHandle& array2, + TestEqualResult& result) const + { + array1.CastAndCallForTypes, vtkm::List>( + *this, array2, result); + } + + VTKM_CONT void operator()(const vtkm::cont::UnknownArrayHandle& array1, + const vtkm::cont::UnknownArrayHandle& array2, + TestEqualResult& result) const + { + array2.CastAndCallForTypes(*this, array1, result); + } + + template + VTKM_CONT void operator()(const vtkm::cont::UncertainArrayHandle& array1, + const vtkm::cont::UncertainArrayHandle& array2, + TestEqualResult& result) const + { + array2.CastAndCall(*this, array1, result); + } }; } // detail diff --git a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx index 09a32fc1b..6307dda58 100644 --- a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -43,6 +45,23 @@ using namespace vtkm::cont::testing::serialization; namespace { +using StorageList = vtkm::List< + vtkm::cont::StorageTagBasic, + vtkm::cont::StorageTagSOA, + vtkm::cont::StorageTagCartesianProduct, + vtkm::cont::StorageTagCast, + vtkm::cont::StorageTagConstant, + vtkm::cont::StorageTagCounting, + vtkm::cont::StorageTagGroupVec, + vtkm::cont::StorageTagGroupVec, + vtkm::cont::StorageTagGroupVec, + vtkm::cont::StorageTagIndex, + vtkm::cont::StorageTagPermutation, + vtkm::cont::StorageTagReverse, + vtkm::cont::StorageTagUniformPoints>; + //----------------------------------------------------------------------------- struct TestEqualArrayHandle { @@ -53,6 +72,14 @@ public: auto result = vtkm::cont::testing::test_equal_ArrayHandles(array1, array2); VTKM_TEST_ASSERT(result, result.GetMergedMessage()); } + + VTKM_CONT void operator()(const vtkm::cont::UnknownArrayHandle& array1, + const vtkm::cont::UnknownArrayHandle& array2) const + { + auto result = vtkm::cont::testing::test_equal_ArrayHandles( + array1.ResetTypes(), + array2.ResetTypes()); + } }; //----------------------------------------------------------------------------- @@ -62,10 +89,24 @@ inline void RunTest(const T& obj) TestSerialization(obj, TestEqualArrayHandle{}); } +template +inline void RunTest(const T& obj, std::true_type) +{ + TestSerialization(obj, TestEqualArrayHandle{}); +} + +template +inline void RunTest(const T&, std::false_type) +{ + // Suppress running the test +} + //----------------------------------------------------------------------------- constexpr vtkm::Id ArraySize = 10; -using TestTypesList = vtkm::List; +using TestTypesListScalar = vtkm::List; +using TestTypesListVec = vtkm::List; +using TestTypesList = vtkm::ListAppend; template inline vtkm::cont::VariantArrayHandleBase>> @@ -74,6 +115,13 @@ MakeTestVariantArrayHandle(const vtkm::cont::ArrayHandle& array) return array; } +template +inline vtkm::cont::UnknownArrayHandle MakeTestUnknownArrayHandle( + const vtkm::cont::ArrayHandle& array) +{ + return array; +} + struct TestArrayHandleBasic { template @@ -81,6 +129,7 @@ struct TestArrayHandleBasic { auto array = RandomArrayHandle::Make(ArraySize); RunTest(array); + RunTest(MakeTestUnknownArrayHandle(array)); RunTest(MakeTestVariantArrayHandle(array)); } }; @@ -93,7 +142,9 @@ struct TestArrayHandleSOA vtkm::cont::ArrayHandleSOA array; vtkm::cont::ArrayCopy(RandomArrayHandle::Make(ArraySize), array); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas{}); } }; @@ -107,7 +158,12 @@ struct TestArrayHandleCartesianProduct RandomArrayHandle::Make(ArraySize), RandomArrayHandle::Make(ArraySize)); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); } }; @@ -119,7 +175,10 @@ struct TestArrayHandleCast auto array = vtkm::cont::make_ArrayHandleCast(RandomArrayHandle::Make(ArraySize)); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); } template @@ -128,7 +187,10 @@ struct TestArrayHandleCast auto array = vtkm::cont::make_ArrayHandleCast>( RandomArrayHandle>::Make(ArraySize)); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); } }; @@ -140,7 +202,9 @@ struct TestArrayHandleConstant T cval = RandomValue::Make(); auto array = vtkm::cont::make_ArrayHandleConstant(cval, ArraySize); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas{}); } }; @@ -153,7 +217,9 @@ struct TestArrayHandleCounting T step = RandomValue::Make(0, 5); auto array = vtkm::cont::make_ArrayHandleCounting(start, step, ArraySize); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas{}); } }; @@ -170,21 +236,30 @@ struct TestArrayHandleGroupVec { auto array = vtkm::cont::make_ArrayHandleGroupVec<3>(flat); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); break; } case 4: { auto array = vtkm::cont::make_ArrayHandleGroupVec<4>(flat); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); break; } default: { auto array = vtkm::cont::make_ArrayHandleGroupVec<2>(flat); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); break; } } @@ -210,9 +285,9 @@ struct TestArrayHandleGroupVecVariable RandomArrayHandle::Make(size), vtkm::cont::make_ArrayHandle(comps, vtkm::CopyFlag::On)); RunTest(array); - // cannot make a VariantArrayHandle containing ArrayHandleGroupVecVariable + // cannot make a UnknownArrayHandle containing ArrayHandleGroupVecVariable // because of the variable number of components of its values. - // RunTest(MakeTestVariantArrayHandle(array)); + // RunTest(MakeTestUnknownArrayHandle(array)); } }; @@ -221,7 +296,9 @@ void TestArrayHandleIndex() auto size = RandomValue::Make(2, 10); auto array = vtkm::cont::ArrayHandleIndex(size); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas{}); } struct TestArrayHandlePermutation @@ -238,7 +315,11 @@ struct TestArrayHandlePermutation RandomArrayHandle::Make(ArraySize, 0, ArraySize - 1), RandomArrayHandle::Make(ArraySize)); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); } }; @@ -249,7 +330,10 @@ struct TestArrayHandleReverse { auto array = vtkm::cont::make_ArrayHandleReverse(RandomArrayHandle::Make(ArraySize)); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas>{}); } }; @@ -266,7 +350,9 @@ void TestArrayHandleUniformPointCoordinates() { auto array = MakeRandomArrayHandleUniformPointCoordinates(); RunTest(array); - RunTest(MakeTestVariantArrayHandle(array)); + RunTest(MakeTestUnknownArrayHandle(array)); + RunTest(MakeTestVariantArrayHandle(array), + vtkm::ListHas{}); } @@ -276,81 +362,38 @@ void TestArrayHandleSerialization() std::cout << "Testing ArrayHandleBasic\n"; vtkm::testing::Testing::TryTypes(TestArrayHandleBasic(), TestTypesList()); - if (vtkm::ListHas::value) - { - std::cout << "Testing ArrayHandleSOA\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleSOA(), TestTypesList()); - } + std::cout << "Testing ArrayHandleSOA\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleSOA(), TestTypesList()); - if (vtkm::ListHas>::value) - { - std::cout << "Testing ArrayHandleCartesianProduct\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleCartesianProduct(), TestTypesList()); - } + std::cout << "Testing ArrayHandleCartesianProduct\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleCartesianProduct(), TestTypesListScalar()); - if (vtkm::ListHas>::value) - { - std::cout << "Testing TestArrayHandleCast\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleCast(), TestTypesList()); - } + std::cout << "Testing TestArrayHandleCast\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleCast(), TestTypesList()); - if (vtkm::ListHas::value) - { - std::cout << "Testing ArrayHandleConstant\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleConstant(), TestTypesList()); - } + std::cout << "Testing ArrayHandleConstant\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleConstant(), TestTypesList()); - if (vtkm::ListHas::value) - { - std::cout << "Testing ArrayHandleCounting\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleCounting(), TestTypesList()); - } + std::cout << "Testing ArrayHandleCounting\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleCounting(), TestTypesList()); - if (vtkm::ListHas>::value) - { - std::cout << "Testing ArrayHandleGroupVec\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVec(), TestTypesList()); - } + std::cout << "Testing ArrayHandleGroupVec\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVec(), TestTypesListScalar()); - if (vtkm::ListHas>::value) - { - std::cout << "Testing ArrayHandleGroupVecVariable\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVecVariable(), TestTypesList()); - } + std::cout << "Testing ArrayHandleGroupVecVariable\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleGroupVecVariable(), TestTypesList()); - if (vtkm::ListHas::value) - { - std::cout << "Testing ArrayHandleIndex\n"; - TestArrayHandleIndex(); - } + std::cout << "Testing ArrayHandleIndex\n"; + TestArrayHandleIndex(); - if (vtkm::ListHas>::value) - { - std::cout << "Testing ArrayHandlePermutation\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandlePermutation(), TestTypesList()); - } + std::cout << "Testing ArrayHandlePermutation\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandlePermutation(), TestTypesList()); - if (vtkm::ListHas>::value) - { - std::cout << "Testing ArrayHandleReverse\n"; - vtkm::testing::Testing::TryTypes(TestArrayHandleReverse(), TestTypesList()); - } + std::cout << "Testing ArrayHandleReverse\n"; + vtkm::testing::Testing::TryTypes(TestArrayHandleReverse(), TestTypesList()); - if (vtkm::ListHas::value) - { - std::cout << "Testing ArrayHandleUniformPointCoordinates\n"; - TestArrayHandleUniformPointCoordinates(); - } + std::cout << "Testing ArrayHandleUniformPointCoordinates\n"; + TestArrayHandleUniformPointCoordinates(); } } // anonymous namespace From c79daa5c2f92752d2e3e8e587212c957d24c8842 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 31 Aug 2020 09:51:53 -0600 Subject: [PATCH 04/51] Suggested changes to comments --- vtkm/cont/Storage.h | 8 +++++++- vtkm/cont/UnknownArrayHandle.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/vtkm/cont/Storage.h b/vtkm/cont/Storage.h index 7ea5dd3fc..a57dcf6a8 100644 --- a/vtkm/cont/Storage.h +++ b/vtkm/cont/Storage.h @@ -50,7 +50,13 @@ namespace cont /// To implement your own StorageTag, you first must create a tag class (an /// empty struct) defining your tag (i.e. struct VTKM_ALWAYS_EXPORT StorageTagMyAlloc { };). Then /// provide a partial template specialization of vtkm::cont::internal::Storage -/// for your new tag. +/// for your new tag. Note that because the StorageTag is being used for +/// template specialization, storage tags cannot use inheritance (or, rather, +/// inheritance won't have any effect). You can, however, have a partial template +/// specialization of vtkm::cont::internal::Storage inherit from a different +/// specialization. So, for example, you could not have StorageTagFoo inherit from +/// StorageTagBase, but you could have vtkm::cont::internal::Storage +/// inherit from vtkm::cont::internal::Storage. /// struct VTKM_ALWAYS_EXPORT StorageTag___ { diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index d797eb168..35d21db33 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -402,7 +402,7 @@ public: } else { - out << "null array" << std::endl; + out << "null UnknownArrayHandle" << std::endl; } } }; From aa6eb01dfe7f7ba54e7fa712423584dedc050c3e Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 31 Aug 2020 16:51:12 -0400 Subject: [PATCH 05/51] ComputeMoments: use FilterField instead of FilterCell --- vtkm/filter/ComputeMoments.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/filter/ComputeMoments.h b/vtkm/filter/ComputeMoments.h index 1d170c417..5e6c74af2 100644 --- a/vtkm/filter/ComputeMoments.h +++ b/vtkm/filter/ComputeMoments.h @@ -17,7 +17,7 @@ namespace vtkm { namespace filter { -class ComputeMoments : public vtkm::filter::FilterCell +class ComputeMoments : public vtkm::filter::FilterField { public: using SupportedTypes = vtkm::List Date: Tue, 1 Sep 2020 10:08:06 -0600 Subject: [PATCH 06/51] Swap call pattern of ArrayHandle::DeepCopy The new method `ArrayHandle::DeepCopy` had the pattern such that the data in the `this` array was pushed to the provided destination array. However, this is the opposite pattern used in the equivalent method in VTK, which takes the data from the provided array and copies it to `this` array. So, swap the pattern to match that of VTK. Also, make the method name more descriptive by renaming it to `DeepCopyFrom`. Hopefully, users will read that to mean given the `ArrayHandle`, you copy data from the other provided `ArrayHandle`. --- vtkm/cont/ArrayCopy.h | 2 +- vtkm/cont/ArrayHandle.h | 10 +++--- vtkm/cont/internal/Buffer.cxx | 31 ++++++++++--------- vtkm/cont/internal/Buffer.h | 8 ++--- vtkm/cont/internal/testing/UnitTestBuffer.cxx | 8 ++--- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/vtkm/cont/ArrayCopy.h b/vtkm/cont/ArrayCopy.h index d1e08ed33..06f588ea9 100644 --- a/vtkm/cont/ArrayCopy.h +++ b/vtkm/cont/ArrayCopy.h @@ -108,7 +108,7 @@ VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, vtkm::cont::ArrayHandle& destination, std::true_type /* New style */) { - source.DeepCopy(destination); + destination.DeepCopyFrom(source); } } // namespace detail diff --git a/vtkm/cont/ArrayHandle.h b/vtkm/cont/ArrayHandle.h index 9e284ce25..c55472045 100644 --- a/vtkm/cont/ArrayHandle.h +++ b/vtkm/cont/ArrayHandle.h @@ -1391,16 +1391,16 @@ public: /// \brief Deep copies the data in the array. /// - /// Takes the data that is in this array and copies that data into the provided - /// \a destination. + /// Takes the data that is in \a source and copies that data into this array. /// - VTKM_CONT void DeepCopy(vtkm::cont::ArrayHandleNewStyle& destination) const + VTKM_CONT void DeepCopyFrom( + const vtkm::cont::ArrayHandleNewStyle& source) const { - VTKM_ASSERT(this->Buffers.size() == destination.Buffers.size()); + VTKM_ASSERT(this->Buffers.size() == source.Buffers.size()); for (std::size_t bufferIndex = 0; bufferIndex < this->Buffers.size(); ++bufferIndex) { - this->Buffers[bufferIndex].DeepCopy(destination.Buffers[bufferIndex]); + this->Buffers[bufferIndex].DeepCopyFrom(source.Buffers[bufferIndex]); } } diff --git a/vtkm/cont/internal/Buffer.cxx b/vtkm/cont/internal/Buffer.cxx index 7af59cd54..9f076d316 100644 --- a/vtkm/cont/internal/Buffer.cxx +++ b/vtkm/cont/internal/Buffer.cxx @@ -768,61 +768,64 @@ void Buffer::Enqueue(const vtkm::cont::Token& token) const detail::BufferHelper::Enqueue(this->Internals, lock, token); } -void Buffer::DeepCopy(vtkm::cont::internal::Buffer& dest) const +void Buffer::DeepCopyFrom(const vtkm::cont::internal::Buffer& src) const { // A Token should not be declared within the scope of a lock. when the token goes out of scope // it will attempt to aquire the lock, which is undefined behavior of the thread already has // the lock. vtkm::cont::Token token; { - LockType srcLock = this->Internals->GetLock(); + const vtkm::cont::internal::Buffer& dest = *this; + + LockType srcLock = src.Internals->GetLock(); LockType destLock = dest.Internals->GetLock(); - detail::BufferHelper::WaitToRead(this->Internals, srcLock, token); + detail::BufferHelper::WaitToRead(src.Internals, srcLock, token); // If we are on a device, copy there. - for (auto&& deviceBuffer : this->Internals->GetDeviceBuffers(srcLock)) + for (auto&& deviceBuffer : src.Internals->GetDeviceBuffers(srcLock)) { if (deviceBuffer.second.UpToDate) { detail::BufferHelper::CopyOnDevice( - deviceBuffer.first, this->Internals, srcLock, dest.Internals, destLock, token); + deviceBuffer.first, src.Internals, srcLock, dest.Internals, destLock, token); return; } } // If we are here, there were no devices to copy on. Copy on host if possible. - if (this->Internals->GetHostBuffer(srcLock).UpToDate) + if (src.Internals->GetHostBuffer(srcLock).UpToDate) { - detail::BufferHelper::CopyOnHost(this->Internals, srcLock, dest.Internals, destLock, token); + detail::BufferHelper::CopyOnHost(src.Internals, srcLock, dest.Internals, destLock, token); } else { // Nothing actually allocated. Just create allocation for dest. (Allocation happens lazily.) detail::BufferHelper::SetNumberOfBytes(dest.Internals, destLock, - this->Internals->GetNumberOfBytes(srcLock), + src.Internals->GetNumberOfBytes(srcLock), vtkm::CopyFlag::Off, token); - if (this->Internals->MetaData) + if (src.Internals->MetaData) { - dest.Internals->MetaData = this->Internals->MetaData->DeepCopy(); + dest.Internals->MetaData = src.Internals->MetaData->DeepCopy(); } } } } -void Buffer::DeepCopy(vtkm::cont::internal::Buffer& dest, vtkm::cont::DeviceAdapterId device) const +void Buffer::DeepCopyFrom(const vtkm::cont::internal::Buffer& src, + vtkm::cont::DeviceAdapterId device) const { // A Token should not be declared within the scope of a lock. when the token goes out of scope // it will attempt to aquire the lock, which is undefined behavior of the thread already has // the lock. vtkm::cont::Token token; { - LockType srcLock = this->Internals->GetLock(); - LockType destLock = dest.Internals->GetLock(); + LockType srcLock = src.Internals->GetLock(); + LockType destLock = this->Internals->GetLock(); detail::BufferHelper::CopyOnDevice( - device, this->Internals, srcLock, dest.Internals, destLock, token); + device, this->Internals, srcLock, this->Internals, destLock, token); } } diff --git a/vtkm/cont/internal/Buffer.h b/vtkm/cont/internal/Buffer.h index 5b04f8afc..d5096ff15 100644 --- a/vtkm/cont/internal/Buffer.h +++ b/vtkm/cont/internal/Buffer.h @@ -226,15 +226,15 @@ public: VTKM_CONT void Enqueue(const vtkm::cont::Token& token) const; /// @{ - /// \brief Copies the data from this buffer to the target buffer. + /// \brief Copies the data from the provided buffer into this buffer. /// /// If a device is given, then the copy will be preferred for that device. Otherwise, a device /// already containing the data will be used for the copy. If no such device exists, the host /// will be used. /// - VTKM_CONT void DeepCopy(vtkm::cont::internal::Buffer& dest) const; - VTKM_CONT void DeepCopy(vtkm::cont::internal::Buffer& dest, - vtkm::cont::DeviceAdapterId device) const; + VTKM_CONT void DeepCopyFrom(const vtkm::cont::internal::Buffer& source) const; + VTKM_CONT void DeepCopyFrom(const vtkm::cont::internal::Buffer& source, + vtkm::cont::DeviceAdapterId device) const; /// @} /// \brief Resets the `Buffer` to the memory allocated at the `BufferInfo`. diff --git a/vtkm/cont/internal/testing/UnitTestBuffer.cxx b/vtkm/cont/internal/testing/UnitTestBuffer.cxx index 7d5b5ef44..e6b0eb6c1 100644 --- a/vtkm/cont/internal/testing/UnitTestBuffer.cxx +++ b/vtkm/cont/internal/testing/UnitTestBuffer.cxx @@ -119,7 +119,7 @@ void DoTest() std::cout << "Copy uninitialized buffer" << std::endl; { vtkm::cont::internal::Buffer copy; - buffer.DeepCopy(copy); + copy.DeepCopyFrom(buffer); VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == 0); VTKM_TEST_ASSERT(CheckMetaData(copy)); } @@ -135,7 +135,7 @@ void DoTest() std::cout << "Copy sized but uninitialized buffer" << std::endl; { vtkm::cont::internal::Buffer copy; - buffer.DeepCopy(copy); + copy.DeepCopyFrom(buffer); VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE); VTKM_TEST_ASSERT(CheckMetaData(copy)); VTKM_TEST_ASSERT(!copy.IsAllocatedOnHost()); @@ -162,7 +162,7 @@ void DoTest() { vtkm::cont::Token token; vtkm::cont::internal::Buffer copy; - buffer.DeepCopy(copy); + copy.DeepCopyFrom(buffer); VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE); VTKM_TEST_ASSERT(CheckMetaData(copy)); VTKM_TEST_ASSERT(copy.IsAllocatedOnHost()); @@ -225,7 +225,7 @@ void DoTest() { vtkm::cont::Token token; vtkm::cont::internal::Buffer copy; - buffer.DeepCopy(copy); + copy.DeepCopyFrom(buffer); VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE); VTKM_TEST_ASSERT(CheckMetaData(copy)); VTKM_TEST_ASSERT(!copy.IsAllocatedOnHost()); From 52cecefba0cd77b1fe5c3f6ada808844c630ac9e Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 1 Sep 2020 14:20:11 -0600 Subject: [PATCH 07/51] Fix crash when loading poly data with no cells --- data/data/unstructured/empty_poly.vtk | 3 +++ data/data/unstructured/empty_unstructured.vtk | 3 +++ vtkm/io/internal/VTKDataSetCells.h | 9 +++++++ vtkm/io/testing/UnitTestVTKDataSetReader.cxx | 26 +++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 data/data/unstructured/empty_poly.vtk create mode 100644 data/data/unstructured/empty_unstructured.vtk diff --git a/data/data/unstructured/empty_poly.vtk b/data/data/unstructured/empty_poly.vtk new file mode 100644 index 000000000..254fd731b --- /dev/null +++ b/data/data/unstructured/empty_poly.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d0ddc7c712a6d544db85660cd9d325884892b18d6f0ed451361aaeae2a96413 +size 204 diff --git a/data/data/unstructured/empty_unstructured.vtk b/data/data/unstructured/empty_unstructured.vtk new file mode 100644 index 000000000..0e69d5656 --- /dev/null +++ b/data/data/unstructured/empty_unstructured.vtk @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75b5601eb23b1724d5309e69a51839615bce625f6e7641b52dc3d06e10b0c5ee +size 745 diff --git a/vtkm/io/internal/VTKDataSetCells.h b/vtkm/io/internal/VTKDataSetCells.h index cbb20bd09..7049e01b1 100644 --- a/vtkm/io/internal/VTKDataSetCells.h +++ b/vtkm/io/internal/VTKDataSetCells.h @@ -210,6 +210,15 @@ inline void FixupCellSet(vtkm::cont::ArrayHandle& connectivity, inline bool IsSingleShape(const vtkm::cont::ArrayHandle& shapes) { + if (shapes.GetNumberOfValues() < 1) + { + // If the data has no cells, is it single shape? That would make sense, but having + // a single shape cell set requires you to slect a shape, and there are no cells to + // make that selection from. We could get around that, but it's easier just to treat + // it as a general explicit grid. + return false; + } + auto shapesPortal = shapes.ReadPortal(); vtkm::UInt8 shape0 = shapesPortal.Get(0); for (vtkm::Id i = 1; i < shapes.GetNumberOfValues(); ++i) diff --git a/vtkm/io/testing/UnitTestVTKDataSetReader.cxx b/vtkm/io/testing/UnitTestVTKDataSetReader.cxx index 51d60b099..3d0bed1d4 100644 --- a/vtkm/io/testing/UnitTestVTKDataSetReader.cxx +++ b/vtkm/io/testing/UnitTestVTKDataSetReader.cxx @@ -62,6 +62,17 @@ void TestReadingPolyData(Format format) "Incorrect cellset type"); } +void TestReadingPolyDataEmpty() +{ + vtkm::cont::DataSet data = + readVTKDataSet(vtkm::cont::testing::Testing::DataPath("unstructured/empty_poly.vtk")); + + VTKM_TEST_ASSERT(data.GetNumberOfPoints() == 8); + VTKM_TEST_ASSERT(data.GetNumberOfCells() == 0); + VTKM_TEST_ASSERT(data.GetCellSet().GetNumberOfPoints() == 8); + VTKM_TEST_ASSERT(data.GetNumberOfFields() == 1); +} + void TestReadingStructuredPoints(Format format) { std::string testFileName = (format == FORMAT_ASCII) @@ -114,6 +125,17 @@ void TestReadingUnstructuredGrid(Format format) "Incorrect cellset type"); } +void TestReadingUnstructuredGridEmpty() +{ + vtkm::cont::DataSet data = + readVTKDataSet(vtkm::cont::testing::Testing::DataPath("unstructured/empty_unstructured.vtk")); + + VTKM_TEST_ASSERT(data.GetNumberOfPoints() == 26); + VTKM_TEST_ASSERT(data.GetNumberOfCells() == 0); + VTKM_TEST_ASSERT(data.GetCellSet().GetNumberOfPoints() == 26); + VTKM_TEST_ASSERT(data.GetNumberOfFields() == 2); +} + void TestReadingUnstructuredGridVisIt(Format format) { VTKM_TEST_ASSERT(format == FORMAT_ASCII); @@ -452,6 +474,8 @@ void TestReadingVTKDataSet() TestReadingPolyData(FORMAT_ASCII); std::cout << "Test reading VTK Polydata file in BINARY" << std::endl; TestReadingPolyData(FORMAT_BINARY); + std::cout << "Test reading VTK Polydata with no cells" << std::endl; + TestReadingPolyDataEmpty(); std::cout << "Test reading VTK StructuredPoints file in ASCII" << std::endl; TestReadingStructuredPoints(FORMAT_ASCII); @@ -461,6 +485,8 @@ void TestReadingVTKDataSet() TestReadingUnstructuredGrid(FORMAT_ASCII); std::cout << "Test reading VTK UnstructuredGrid file in BINARY" << std::endl; TestReadingUnstructuredGrid(FORMAT_BINARY); + std::cout << "Test reading VTK UnstructuredGrid with no cells" << std::endl; + TestReadingUnstructuredGridEmpty(); std::cout << "Test reading VTK RectilinearGrid file in ASCII" << std::endl; TestReadingRectilinearGrid1(FORMAT_ASCII); From 3f8da6e7e11864885e16917418dd0252061c1077 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 1 Sep 2020 14:21:09 -0600 Subject: [PATCH 08/51] Fix some debugging code that should not have been there --- vtkm/filter/testing/UnitTestContourFilter.cxx | 4 +++- vtkm/io/VTKUnstructuredGridReader.cxx | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/vtkm/filter/testing/UnitTestContourFilter.cxx b/vtkm/filter/testing/UnitTestContourFilter.cxx index da1a2d38a..6a085fb59 100644 --- a/vtkm/filter/testing/UnitTestContourFilter.cxx +++ b/vtkm/filter/testing/UnitTestContourFilter.cxx @@ -140,12 +140,14 @@ public: void TestContourWedges() const { + std::cout << "Testing Contour filter on wedge cells" << std::endl; + auto pathname = vtkm::cont::testing::Testing::DataPath("unstructured/wedge_cells.vtk"); vtkm::io::VTKDataSetReader reader(pathname); vtkm::cont::DataSet dataSet = reader.ReadDataSet(); - vtkm::cont::CellSetExplicit<> cellSet; + vtkm::cont::CellSetSingleType<> cellSet; dataSet.GetCellSet().CopyTo(cellSet); vtkm::cont::ArrayHandle fieldArray; diff --git a/vtkm/io/VTKUnstructuredGridReader.cxx b/vtkm/io/VTKUnstructuredGridReader.cxx index 0fb69cacb..8a5a0b136 100644 --- a/vtkm/io/VTKUnstructuredGridReader.cxx +++ b/vtkm/io/VTKUnstructuredGridReader.cxx @@ -65,8 +65,7 @@ void VTKUnstructuredGridReader::Read() vtkm::io::internal::FixupCellSet(connectivity, numIndices, shapes, permutation); this->SetCellsPermutation(permutation); - //DRP - if (false) //vtkm::io::internal::IsSingleShape(shapes)) + if (vtkm::io::internal::IsSingleShape(shapes)) { vtkm::cont::CellSetSingleType<> cellSet; cellSet.Fill( From 66a4a23ebf6cf04cbab970949b279d8b5e1d48f9 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 2 Sep 2020 10:56:31 -0600 Subject: [PATCH 09/51] Fix issue of getting pointer from std::vector of size 0 C++11 introduced the `std::vector::data()` method. In addition to being more syntatically pleasing, it should correctly handle the condition when the `std::vector` is size 0 and therefore has no real pointer. (Expressions like `&v[0]` are undefined when the `vector` is empty.) --- vtkm/io/VTKDataSetReaderBase.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vtkm/io/VTKDataSetReaderBase.cxx b/vtkm/io/VTKDataSetReaderBase.cxx index 40fa21fd2..479d1f720 100644 --- a/vtkm/io/VTKDataSetReaderBase.cxx +++ b/vtkm/io/VTKDataSetReaderBase.cxx @@ -267,7 +267,7 @@ void VTKDataSetReaderBase::ReadCells(vtkm::cont::ArrayHandle& connecti std::vector buffer(static_cast(numInts)); this->ReadArray(buffer); - vtkm::Int32* buffp = &buffer[0]; + vtkm::Int32* buffp = buffer.data(); auto connectivityPortal = connectivity.WritePortal(); auto numIndicesPortal = numIndices.WritePortal(); for (vtkm::Id i = 0, connInd = 0; i < numCells; ++i) @@ -292,7 +292,7 @@ void VTKDataSetReaderBase::ReadShapes(vtkm::cont::ArrayHandle& shap std::vector buffer(static_cast(numCells)); this->ReadArray(buffer); - vtkm::Int32* buffp = &buffer[0]; + vtkm::Int32* buffp = buffer.data(); auto shapesPortal = shapes.WritePortal(); for (vtkm::Id i = 0; i < numCells; ++i) { From bb443bbc24767fa4cafe15cf72da0fa6a3dea150 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 2 Sep 2020 15:02:44 -0600 Subject: [PATCH 10/51] Replace the implementation of VariantArrayHandle The implementation of `VariantArrayHandle` has been changed to be a relatively trivial subclass of `UnknownArrayHandle`. The advantage of this change is twofold. First, it removes `VariantArrayHandle`'s dependence on `ArrayHandleVirtual`, which gets us much closer to deprecating that class. Second, it ensures that `UnknownArrayHandle` is a reasonable replacement for `VariantArrayHandle`, so we can move forward with replacing that. --- vtkm/cont/CMakeLists.txt | 1 - vtkm/cont/UnknownArrayHandle.h | 14 +- vtkm/cont/VariantArrayHandle.h | 430 ++++-------------- vtkm/cont/internal/CMakeLists.txt | 1 - .../internal/VariantArrayHandleContainer.cxx | 68 --- .../internal/VariantArrayHandleContainer.h | 301 ------------ .../testing/UnitTestArrayHandleVirtual.cxx | 1 + .../testing/UnitTestVariantArrayHandle.cxx | 11 +- 8 files changed, 120 insertions(+), 707 deletions(-) delete mode 100644 vtkm/cont/internal/VariantArrayHandleContainer.cxx delete mode 100644 vtkm/cont/internal/VariantArrayHandleContainer.h diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index 46707847a..602225369 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -183,7 +183,6 @@ set(sources DataSetBuilderExplicit.cxx DataSetBuilderRectilinear.cxx DataSetBuilderUniform.cxx - internal/VariantArrayHandleContainer.cxx Field.cxx FieldRangeCompute.cxx FieldRangeGlobalCompute.cxx diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index 35d21db33..e185e99ce 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -220,6 +220,7 @@ class VTKM_CONT_EXPORT UnknownArrayHandle public: VTKM_CONT UnknownArrayHandle() = default; + UnknownArrayHandle(const UnknownArrayHandle&) = default; template VTKM_CONT UnknownArrayHandle(const vtkm::cont::ArrayHandle& array) @@ -227,6 +228,8 @@ public: { } + UnknownArrayHandle& operator=(const vtkm::cont::UnknownArrayHandle&) = default; + /// \brief Create a new array of the same type as this array. /// /// This method creates a new array that is the same type as this one and @@ -476,8 +479,17 @@ struct UnknownArrayHandleMultplexerCastTry bool& converted) const { using ArrayType = vtkm::cont::ArrayHandle; - if (!converted && unknownArray.CanConvert()) + if (unknownArray.CanConvert()) { + if (converted && !unknownArray.IsType()) + { + // The array has already been converted and pushed in the multiplexer. It is + // possible that multiple array types can be put in the ArrayHandleMultiplexer + // (for example, and ArrayHandle or an ArrayHandle that has been cast). Exact + // matches will override other matches (hence, the second part of the condition), + // but at this point we have already found a better array to put inside. + return; + } outputArray.GetStorage().SetArray(unknownArray.AsArrayHandle()); converted = true; } diff --git a/vtkm/cont/VariantArrayHandle.h b/vtkm/cont/VariantArrayHandle.h index a836d1b74..3d52aa0fb 100644 --- a/vtkm/cont/VariantArrayHandle.h +++ b/vtkm/cont/VariantArrayHandle.h @@ -23,14 +23,71 @@ #include #include #include - -#include +#include +#include namespace vtkm { namespace cont { +namespace internal +{ +namespace variant +{ + +struct ForceCastToVirtual +{ + template + VTKM_CONT typename std::enable_if::value>::type + operator()(const vtkm::cont::ArrayHandle& input, + vtkm::cont::ArrayHandleVirtual& output) const + { // ValueTypes match + output = vtkm::cont::make_ArrayHandleVirtual(input); + } + + template + VTKM_CONT typename std::enable_if::value>::type + operator()(const vtkm::cont::ArrayHandle& input, + vtkm::cont::ArrayHandleVirtual& output) const + { // ValueTypes do not match + this->ValidateWidthAndCast(input, output); + } + +private: + template ::NUM_COMPONENTS, + vtkm::IdComponent DSize = vtkm::VecTraits::NUM_COMPONENTS> + VTKM_CONT typename std::enable_if::type ValidateWidthAndCast( + const InputType& input, + vtkm::cont::ArrayHandleVirtual& output) const + { // number of components match + auto casted = vtkm::cont::make_ArrayHandleCast(input); + output = vtkm::cont::make_ArrayHandleVirtual(casted); + } + + template ::NUM_COMPONENTS, + vtkm::IdComponent DSize = vtkm::VecTraits::NUM_COMPONENTS> + VTKM_CONT typename std::enable_if::type ValidateWidthAndCast( + const ArrayHandleBase&, + ArrayHandleBase&) const + { // number of components do not match + std::ostringstream str; + str << "VariantArrayHandle::AsVirtual: Cannot cast from " << vtkm::cont::TypeToString() + << " to " << vtkm::cont::TypeToString() + << "; " + "number of components must match exactly."; + throw vtkm::cont::ErrorBadType(str.str()); + } +}; + +} +} // namespace internal::variant + /// \brief VariantArrayHandle superclass holding common operations. /// /// `VariantArrayHandleCommon` is a superclass to all `VariantArrayHandleBase` @@ -40,43 +97,20 @@ namespace cont /// /// See the documentation of `VariantArrayHandleBase` for more information. /// -class VTKM_ALWAYS_EXPORT VariantArrayHandleCommon +class VTKM_ALWAYS_EXPORT VariantArrayHandleCommon : public vtkm::cont::UnknownArrayHandle { - std::shared_ptr ArrayContainer; + using Superclass = vtkm::cont::UnknownArrayHandle; public: + using Superclass::Superclass; + VTKM_CONT VariantArrayHandleCommon() = default; - template - VTKM_CONT VariantArrayHandleCommon(const vtkm::cont::ArrayHandle& array) - : ArrayContainer(std::make_shared>( - vtkm::cont::ArrayHandleVirtual{ array })) + VTKM_CONT VariantArrayHandleCommon(const vtkm::cont::UnknownArrayHandle& array) + : Superclass(array) { } - template - VTKM_CONT VariantArrayHandleCommon( - const vtkm::cont::ArrayHandle& array) - : ArrayContainer(std::make_shared>(array)) - { - } - - /// Returns true if this array matches the array handle type passed in. - /// - template - VTKM_CONT bool IsType() const - { - return internal::variant::IsType(this->ArrayContainer.get()); - } - - /// Returns true if this array matches the ValueType type passed in. - /// - template - VTKM_CONT bool IsValueType() const - { - return internal::variant::IsValueType(this->ArrayContainer.get()); - } - /// Returns this array cast to the given \c ArrayHandle type. Throws \c /// ErrorBadType if the cast does not work. Use \c IsType /// to check if the cast can happen. @@ -84,18 +118,7 @@ public: template VTKM_CONT ArrayHandleType Cast() const { -// MSVC will issue deprecation warnings if this templated method is instantiated with -// a deprecated class here even if the method is called from a section of code where -// deprecation warnings are suppressed. This is annoying behavior since this templated -// method has no control over what class it is used from. To get around it, we have to -// suppress all deprecation warnings here. -#ifdef VTKM_MSVC - VTKM_DEPRECATED_SUPPRESS_BEGIN -#endif - return internal::variant::Cast(this->ArrayContainer.get()); -#ifdef VTKM_MSVC - VTKM_DEPRECATED_SUPPRESS_END -#endif + return this->AsArrayHandle(); } /// \brief Call a functor using the underlying array type. @@ -106,7 +129,11 @@ public: /// calling differs from that of the `CastAndCall` methods of subclasses.) /// template - VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const; + VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const + { + this->CastAndCallForTypes(std::forward(functor), + std::forward(args)...); + } /// Returns this array cast to a `ArrayHandleVirtual` of the given type. /// This will perform type conversions as necessary, and will log warnings @@ -141,7 +168,10 @@ public: /// ///@{ template - VTKM_CONT void AsMultiplexer(vtkm::cont::ArrayHandleMultiplexer& result) const; + VTKM_CONT void AsMultiplexer(vtkm::cont::ArrayHandleMultiplexer& result) const + { + this->AsArrayHandle(result); + } template VTKM_CONT ArrayHandleMultiplexerType AsMultiplexer() const @@ -175,40 +205,8 @@ public: /// VTKM_CONT VariantArrayHandleCommon NewInstance() const { - VariantArrayHandleCommon instance; - instance.ArrayContainer = this->ArrayContainer->NewInstance(); - return instance; + return VariantArrayHandleCommon(this->Superclass::NewInstance()); } - - /// Releases any resources being used in the execution environment (that are - /// not being shared by the control environment). - /// - void ReleaseResourcesExecution() { return this->ArrayContainer->ReleaseResourcesExecution(); } - - - /// Releases all resources in both the control and execution environments. - /// - void ReleaseResources() { return this->ArrayContainer->ReleaseResources(); } - - /// \brief Get the number of components in each array value. - /// - /// This method will query the array type for the number of components in - /// each value of the array. The number of components is determined by - /// the \c VecTraits::NUM_COMPONENTS trait class. - /// - VTKM_CONT - vtkm::IdComponent GetNumberOfComponents() const - { - return this->ArrayContainer->GetNumberOfComponents(); - } - - /// \brief Get the number of values in the array. - /// - VTKM_CONT - vtkm::Id GetNumberOfValues() const { return this->ArrayContainer->GetNumberOfValues(); } - - VTKM_CONT - void PrintSummary(std::ostream& out) const { this->ArrayContainer->PrintSummary(out); } }; /// \brief Holds an array handle without having to specify template parameters. @@ -263,6 +261,18 @@ public: { } + VTKM_CONT explicit VariantArrayHandleBase(const vtkm::cont::UnknownArrayHandle& src) + : Superclass(src) + { + } + + template + VTKM_CONT VariantArrayHandleBase( + const vtkm::cont::UncertainArrayHandle& src) + : Superclass(src) + { + } + VTKM_CONT VariantArrayHandleBase(const VariantArrayHandleBase&) = default; VTKM_CONT VariantArrayHandleBase(VariantArrayHandleBase&&) noexcept = default; @@ -276,6 +286,11 @@ public: VariantArrayHandleBase& operator=(VariantArrayHandleBase&&) noexcept = default; + VTKM_CONT operator vtkm::cont::UncertainArrayHandle() const + { + return vtkm::cont::UncertainArrayHandle(*this); + } + /// Returns this array cast to a \c ArrayHandleVirtual of the given type. /// This will perform type conversions as necessary, and will log warnings @@ -392,207 +407,6 @@ VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::VariantArrayHandleBase(); } -//============================================================================= -// Out of class implementations - -namespace detail -{ - -struct VariantArrayHandleTry -{ - template - void operator()(vtkm::List, - Functor&& f, - bool& called, - const vtkm::cont::internal::VariantArrayHandleContainerBase& container, - Args&&... args) const - { - using DerivedArrayType = vtkm::cont::ArrayHandle; - if (!called && vtkm::cont::internal::variant::IsType(&container)) - { - called = true; - const auto* derivedContainer = - static_cast*>(&container); - DerivedArrayType derivedArray = derivedContainer->Array.template Cast(); - VTKM_LOG_CAST_SUCC(container, derivedArray); - - // If you get a compile error here, it means that you have called CastAndCall for a - // vtkm::cont::VariantArrayHandle and the arguments of the functor do not match those - // being passed. This is often because it is calling the functor with an ArrayHandle - // type that was not expected. Either add overloads to the functor to accept all - // possible array types or constrain the types tried for the CastAndCall. Note that - // the functor will be called with an array of type vtkm::cont::ArrayHandle. - // Directly using a subclass of ArrayHandle (e.g. vtkm::cont::ArrayHandleConstant) - // might not work. - f(derivedArray, std::forward(args)...); - } - } -}; - -template -struct IsUndefinedStorage -{ -}; -template -struct IsUndefinedStorage> : vtkm::cont::internal::IsInvalidArrayHandle -{ -}; - -template -using ListDynamicTypes = - vtkm::ListRemoveIf, IsUndefinedStorage>; - - -} // namespace detail - - - -template -VTKM_CONT void VariantArrayHandleCommon::CastAndCall(Functor&& f, Args&&... args) const -{ - using crossProduct = detail::ListDynamicTypes; - - bool called = false; - const auto& ref = *this->ArrayContainer; - vtkm::ListForEach(detail::VariantArrayHandleTry{}, - crossProduct{}, - std::forward(f), - called, - ref, - std::forward(args)...); - if (!called) - { - // throw an exception - VTKM_LOG_CAST_FAIL(*this, TypeList); - detail::ThrowCastAndCallException(ref, typeid(TypeList)); - } -} - -namespace detail -{ - -struct VariantArrayHandleTryMultiplexer -{ - template - VTKM_CONT void operator()(const vtkm::cont::ArrayHandle&, - const vtkm::cont::VariantArrayHandleCommon& self, - vtkm::cont::ArrayHandleMultiplexer& result) const - { - vtkm::cont::ArrayHandle targetArray; - bool foundArray = false; - this->FetchArray(targetArray, self, foundArray, result.IsValid()); - if (foundArray) - { - result.SetArray(targetArray); - VTKM_LOG_CAST_SUCC(self, result); - } - } - -private: - template - VTKM_CONT void FetchArrayExact(vtkm::cont::ArrayHandle& targetArray, - const vtkm::cont::VariantArrayHandleCommon& self, - bool& foundArray) const - { - using ArrayType = vtkm::cont::ArrayHandle; - if (self.IsType()) - { - targetArray = self.Cast(); - foundArray = true; - } - else - { - foundArray = false; - } - } - - template - VTKM_CONT void FetchArray(vtkm::cont::ArrayHandle& targetArray, - const vtkm::cont::VariantArrayHandleCommon& self, - bool& foundArray, - bool vtkmNotUsed(foundArrayInPreviousCall)) const - { - this->FetchArrayExact(targetArray, self, foundArray); - } - - // Special condition for transformed arrays. Instead of pulling out the - // transform, pull out the array that is being transformed. - template - VTKM_CONT void FetchArray( - vtkm::cont::ArrayHandle< - T, - vtkm::cont::internal::StorageTagTransform>& - targetArray, - const vtkm::cont::VariantArrayHandleCommon& self, - bool& foundArray, - bool foundArrayInPreviousCall) const - { - // Attempt to get the array itself first - this->FetchArrayExact(targetArray, self, foundArray); - - // Try to get the array to be transformed first, but only do so if the array was not already - // found in another call to this functor. This is to give precedence to getting the array - // exactly rather than creating our own transform. - if (!foundArray && !foundArrayInPreviousCall) - { - SrcArray srcArray; - this->FetchArray(srcArray, self, foundArray, foundArrayInPreviousCall); - if (foundArray) - { - targetArray = - vtkm::cont::ArrayHandleTransform(srcArray); - } - } - } - - // Special condition for cast arrays. Instead of pulling out an ArrayHandleCast, pull out - // the array that is being cast. - template - VTKM_CONT void FetchArray( - vtkm::cont::ArrayHandle>& - targetArray, - const vtkm::cont::VariantArrayHandleCommon& self, - bool& foundArray, - bool foundArrayInPreviousCall) const - { - // Attempt to get the array itself first - this->FetchArrayExact(targetArray, self, foundArray); - - // Try to get the array to be transformed first, but only do so if the array was not already - // found in another call to this functor. This is to give precedence to getting the array - // exactly rather than creating our own transform. - if (!foundArray && !foundArrayInPreviousCall) - { - using SrcArray = vtkm::cont::ArrayHandle; - SrcArray srcArray; - this->FetchArray(srcArray, self, foundArray, foundArrayInPreviousCall); - if (foundArray) - { - targetArray = - vtkm::cont::ArrayHandleCast>( - srcArray); - } - } - } -}; - -} // namespace detail - -template -inline VTKM_CONT void VariantArrayHandleCommon::AsMultiplexer( - vtkm::cont::ArrayHandleMultiplexer& result) const -{ - // Make sure IsValid is clear - result = vtkm::cont::ArrayHandleMultiplexer{}; - vtkm::ListForEach(detail::VariantArrayHandleTryMultiplexer{}, vtkm::List{}, *this, result); - if (!result.IsValid()) - { - // Could not put the class into the multiplexer. Throw an exception. - VTKM_LOG_CAST_FAIL(*this, vtkm::List); - detail::ThrowAsMultiplexerException(*this->ArrayContainer, { typeid(T).name()... }); - } -} - namespace internal { @@ -612,72 +426,24 @@ struct DynamicTransformTraits> namespace mangled_diy_namespace { -namespace internal -{ - -struct VariantArrayHandleSerializeFunctor -{ - template - void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const - { - vtkmdiy::save(bb, vtkm::cont::SerializableTypeString::Get()); - vtkmdiy::save(bb, ah); - } -}; - -struct VariantArrayHandleDeserializeFunctor -{ - template - void operator()(vtkm::List, - vtkm::cont::VariantArrayHandleBase& dh, - const std::string& typeString, - bool& success, - BinaryBuffer& bb) const - { - using ArrayHandleType = vtkm::cont::ArrayHandle; - - if (!success && (typeString == vtkm::cont::SerializableTypeString::Get())) - { - ArrayHandleType ah; - vtkmdiy::load(bb, ah); - dh = vtkm::cont::VariantArrayHandleBase(ah); - success = true; - } - } -}; - -} // internal - template struct Serialization> { private: using Type = vtkm::cont::VariantArrayHandleBase; + using ImplObject = vtkm::cont::UncertainArrayHandle; public: static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj) { - obj.CastAndCall(internal::VariantArrayHandleSerializeFunctor{}, bb); + vtkmdiy::save(bb, ImplObject(obj)); } static VTKM_CONT void load(BinaryBuffer& bb, Type& obj) { - std::string typeString; - vtkmdiy::load(bb, typeString); - - bool success = false; - vtkm::ListForEach(internal::VariantArrayHandleDeserializeFunctor{}, - vtkm::cont::detail::ListDynamicTypes{}, - obj, - typeString, - success, - bb); - - if (!success) - { - throw vtkm::cont::ErrorBadType( - "Error deserializing VariantArrayHandle. Message TypeString: " + typeString); - } + ImplObject implObj; + vtkmdiy::load(bb, implObj); + obj = implObj; } }; diff --git a/vtkm/cont/internal/CMakeLists.txt b/vtkm/cont/internal/CMakeLists.txt index 3736cd024..73f8f7eda 100644 --- a/vtkm/cont/internal/CMakeLists.txt +++ b/vtkm/cont/internal/CMakeLists.txt @@ -33,7 +33,6 @@ set(headers ReverseConnectivityBuilder.h StorageError.h TransferInfo.h - VariantArrayHandleContainer.h VirtualObjectTransfer.h VirtualObjectTransferInstantiate.h VirtualObjectTransferShareWithControl.h diff --git a/vtkm/cont/internal/VariantArrayHandleContainer.cxx b/vtkm/cont/internal/VariantArrayHandleContainer.cxx deleted file mode 100644 index 58a55278f..000000000 --- a/vtkm/cont/internal/VariantArrayHandleContainer.cxx +++ /dev/null @@ -1,68 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ - -#include -#include - -#include -#include - -namespace vtkm -{ -namespace cont -{ -namespace internal -{ - -VariantArrayHandleContainerBase::VariantArrayHandleContainerBase() - : TypeIndex(typeid(nullptr)) -{ -} - -VariantArrayHandleContainerBase::VariantArrayHandleContainerBase(const std::type_info& typeinfo) - : TypeIndex(typeinfo) -{ -} - -VariantArrayHandleContainerBase::~VariantArrayHandleContainerBase() {} -} - -namespace detail -{ -VTKM_CONT_EXPORT void ThrowCastAndCallException( - const vtkm::cont::internal::VariantArrayHandleContainerBase& ref, - const std::type_info& type) -{ - std::ostringstream out; - out << "Could not find appropriate cast for array in CastAndCall.\n" - "Array: "; - ref.PrintSummary(out); - out << "TypeList: " << type.name() << "\n"; - throw vtkm::cont::ErrorBadValue(out.str()); -} - -VTKM_CONT_EXPORT void ThrowAsMultiplexerException( - const vtkm::cont::internal::VariantArrayHandleContainerBase& ref, - const std::initializer_list& arrayTypes) -{ - std::ostringstream out; - out << "Could not find appropriate cast for array in AsMultiplexer.\n" - "Array: "; - ref.PrintSummary(out); - out << "Supported arrays:\n"; - for (auto&& type : arrayTypes) - { - out << " " << type << "\n"; - } - throw vtkm::cont::ErrorBadValue(out.str()); -} -} -} -} // namespace vtkm::cont::detail diff --git a/vtkm/cont/internal/VariantArrayHandleContainer.h b/vtkm/cont/internal/VariantArrayHandleContainer.h deleted file mode 100644 index e8cde110b..000000000 --- a/vtkm/cont/internal/VariantArrayHandleContainer.h +++ /dev/null @@ -1,301 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ -#ifndef vtk_m_cont_VariantArrayHandleContainer_h -#define vtk_m_cont_VariantArrayHandleContainer_h - -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include - -namespace vtkm -{ -namespace cont -{ - -// Forward declaration needed for GetContainer -template -class VariantArrayHandleBase; - -namespace internal -{ - -/// \brief Base class for VariantArrayHandleContainer -/// -struct VTKM_CONT_EXPORT VariantArrayHandleContainerBase -{ - std::type_index TypeIndex; - - VariantArrayHandleContainerBase(); - explicit VariantArrayHandleContainerBase(const std::type_info& hash); - - // This must exist so that subclasses are destroyed correctly. - virtual ~VariantArrayHandleContainerBase(); - - virtual vtkm::Id GetNumberOfValues() const = 0; - virtual vtkm::IdComponent GetNumberOfComponents() const = 0; - - virtual void ReleaseResourcesExecution() = 0; - virtual void ReleaseResources() = 0; - - virtual void PrintSummary(std::ostream& out) const = 0; - - virtual std::shared_ptr NewInstance() const = 0; -}; - -/// \brief ArrayHandle container that can use C++ run-time type information. -/// -/// The \c VariantArrayHandleContainer holds ArrayHandle objects -/// (with different template parameters) so that it can polymorphically answer -/// simple questions about the object. -/// -template -struct VTKM_ALWAYS_EXPORT VariantArrayHandleContainer final : public VariantArrayHandleContainerBase -{ - vtkm::cont::ArrayHandleVirtual Array; - mutable vtkm::IdComponent NumberOfComponents = 0; - - VariantArrayHandleContainer() - : VariantArrayHandleContainerBase(typeid(T)) - , Array() - { - } - - VariantArrayHandleContainer(const vtkm::cont::ArrayHandleVirtual& array) - : VariantArrayHandleContainerBase(typeid(T)) - , Array(array) - { - } - - ~VariantArrayHandleContainer() override = default; - - vtkm::Id GetNumberOfValues() const override { return this->Array.GetNumberOfValues(); } - - vtkm::IdComponent GetNumberOfComponents() const override - { - // Cache number of components to avoid unnecessary device to host transfers of the array. - // Also assumes that the number of components is constant accross all elements and - // throughout the life of the array. - if (this->NumberOfComponents == 0) - { - this->NumberOfComponents = - this->GetNumberOfComponents(typename vtkm::VecTraits::IsSizeStatic{}); - } - return this->NumberOfComponents; - } - - void ReleaseResourcesExecution() override { this->Array.ReleaseResourcesExecution(); } - void ReleaseResources() override { this->Array.ReleaseResources(); } - - void PrintSummary(std::ostream& out) const override - { - vtkm::cont::printSummary_ArrayHandle(this->Array, out); - } - - std::shared_ptr NewInstance() const override - { - return std::make_shared>(this->Array.NewInstance()); - } - -private: - vtkm::IdComponent GetNumberOfComponents(VecTraitsTagSizeStatic) const - { - return vtkm::VecTraits::NUM_COMPONENTS; - } - - vtkm::IdComponent GetNumberOfComponents(VecTraitsTagSizeVariable) const - { - return (this->Array.GetNumberOfValues() == 0) - ? 0 - : vtkm::VecTraits::GetNumberOfComponents(this->Array.ReadPortal().Get(0)); - } -}; - -namespace variant -{ - -// One instance of a template class cannot access the private members of -// another instance of a template class. However, I want to be able to copy -// construct a VariantArrayHandle from another VariantArrayHandle of any other -// type. Since you cannot partially specialize friendship, use this accessor -// class to get at the internals for the copy constructor. -struct GetContainer -{ - template - VTKM_CONT static const std::shared_ptr& Extract( - const vtkm::cont::VariantArrayHandleBase& src) - { - return src.ArrayContainer; - } -}; - -template -VTKM_CONT bool IsValueType(const VariantArrayHandleContainerBase* container) -{ - if (container == nullptr) - { //you can't use typeid on nullptr of polymorphic types - return false; - } - - //needs optimizations based on platform. !OSX can use typeid - return container->TypeIndex == std::type_index(typeid(T)); - // return (nullptr != dynamic_cast*>(container)); -} - -template -VTKM_CONT inline bool IsType(const VariantArrayHandleContainerBase* container) -{ //container could be nullptr - using T = typename ArrayHandleType::ValueType; - if (!IsValueType(container)) - { - return false; - } - - const auto* derived = static_cast*>(container); - return vtkm::cont::IsType(derived->Array); -} - -template -struct VTKM_ALWAYS_EXPORT Caster -{ - vtkm::cont::ArrayHandle operator()(const VariantArrayHandleContainerBase* container) const - { - //This needs to be reworked - using ArrayHandleType = vtkm::cont::ArrayHandle; - if (!IsValueType(container)) - { - VTKM_LOG_CAST_FAIL(container, ArrayHandleType); - throwFailedDynamicCast(vtkm::cont::TypeToString(container), - vtkm::cont::TypeToString()); - } - - const auto* derived = static_cast*>(container); - return vtkm::cont::Cast>(derived->Array); - } -}; - -template -struct VTKM_ALWAYS_EXPORT Caster -{ - vtkm::cont::ArrayHandle operator()( - const VariantArrayHandleContainerBase* container) const - { - if (!IsValueType(container)) - { - VTKM_LOG_CAST_FAIL(container, vtkm::cont::ArrayHandleVirtual); - throwFailedDynamicCast(vtkm::cont::TypeToString(container), - vtkm::cont::TypeToString>()); - } - - // Technically, this method returns a copy of the \c ArrayHandle. But - // because \c ArrayHandle acts like a shared pointer, it is valid to - // do the copy. - const auto* derived = static_cast*>(container); - VTKM_LOG_CAST_SUCC(container, derived->Array); - return derived->Array; - } -}; - -// MSVC will issue deprecation warnings here if this template is instantiated with -// a deprecated class even if the template is used from a section of code where -// deprecation warnings are suppressed. This is annoying behavior since this template -// has no control over what class it is used with. To get around it, we have to -// suppress all deprecation warnings here. -#ifdef VTKM_MSVC -VTKM_DEPRECATED_SUPPRESS_BEGIN -#endif -template -VTKM_CONT ArrayHandleType Cast(const VariantArrayHandleContainerBase* container) -{ //container could be nullptr - VTKM_IS_ARRAY_HANDLE(ArrayHandleType); - using Type = typename ArrayHandleType::ValueType; - using Storage = typename ArrayHandleType::StorageTag; - auto ret = Caster{}(container); - return ArrayHandleType(std::move(ret)); -} -#ifdef VTKM_MSVC -VTKM_DEPRECATED_SUPPRESS_END -#endif - -struct ForceCastToVirtual -{ - template - VTKM_CONT typename std::enable_if::value>::type - operator()(const vtkm::cont::ArrayHandle& input, - vtkm::cont::ArrayHandleVirtual& output) const - { // ValueTypes match - output = vtkm::cont::make_ArrayHandleVirtual(input); - } - - template - VTKM_CONT typename std::enable_if::value>::type - operator()(const vtkm::cont::ArrayHandle& input, - vtkm::cont::ArrayHandleVirtual& output) const - { // ValueTypes do not match - this->ValidateWidthAndCast(input, output); - } - -private: - template ::NUM_COMPONENTS, - vtkm::IdComponent DSize = vtkm::VecTraits::NUM_COMPONENTS> - VTKM_CONT typename std::enable_if::type ValidateWidthAndCast( - const InputType& input, - vtkm::cont::ArrayHandleVirtual& output) const - { // number of components match - auto casted = vtkm::cont::make_ArrayHandleCast(input); - output = vtkm::cont::make_ArrayHandleVirtual(casted); - } - - template ::NUM_COMPONENTS, - vtkm::IdComponent DSize = vtkm::VecTraits::NUM_COMPONENTS> - VTKM_CONT typename std::enable_if::type ValidateWidthAndCast( - const ArrayHandleBase&, - ArrayHandleBase&) const - { // number of components do not match - std::ostringstream str; - str << "VariantArrayHandle::AsVirtual: Cannot cast from " << vtkm::cont::TypeToString() - << " to " << vtkm::cont::TypeToString() - << "; " - "number of components must match exactly."; - throw vtkm::cont::ErrorBadType(str.str()); - } -}; -} // namespace variant - -} // namespace internal - -namespace detail -{ - -VTKM_CONT_EXPORT void ThrowCastAndCallException( - const vtkm::cont::internal::VariantArrayHandleContainerBase&, - const std::type_info&); - -VTKM_CONT_EXPORT void ThrowAsMultiplexerException( - const vtkm::cont::internal::VariantArrayHandleContainerBase& ref, - const std::initializer_list& arrayTypes); -} // namespace detail -} -} //namespace vtkm::cont - -#endif diff --git a/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx b/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx index c91e39d92..084cca8b3 100644 --- a/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx +++ b/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx @@ -11,6 +11,7 @@ #include #include #include +#include #include diff --git a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx index 820a76764..98a74438b 100644 --- a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx @@ -230,11 +230,16 @@ void CheckCastToArrayHandle(const ArrayHandleType& array) ArrayHandleType castArray1; arrayVariant.CopyTo(castArray1); - VTKM_TEST_ASSERT(arrayVariant.IsType(), "Did not query handle correctly."); - VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array."); + VTKM_TEST_ASSERT(arrayVariant.CanConvert(), "Did not query handle correctly."); + //VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array."); + auto result = vtkm::cont::testing::test_equal_ArrayHandles(array, castArray1); + VTKM_TEST_ASSERT(result, result.GetMergedMessage()); + ArrayHandleType castArray2 = arrayVariant.Cast(); - VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array."); + //VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array."); + result = vtkm::cont::testing::test_equal_ArrayHandles(array, castArray2); + VTKM_TEST_ASSERT(result, result.GetMergedMessage()); } // A vtkm::Vec if NumComps > 1, otherwise a scalar From 872da1f8e61265f6a408f88ae36cdf70b1e1a892 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 2 Sep 2020 16:48:11 -0600 Subject: [PATCH 11/51] Suppress unnecessary deprecation warnings on VS The Visual Studio compiler has an annoying habit where if you use a templated class or method with a deprecated class as a template parameter, you will get a deprecation warning where that class is used in the templated thing. Thus, if you want to suppress the warning, you have to supress every instance of the template, not just where the template is declared. This is annoying behavior that is thankfully not replicated in other compilers. --- vtkm/cont/UnknownArrayHandle.h | 11 +++++++++++ vtkm/cont/VariantArrayHandle.h | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index e185e99ce..9a3d0119f 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -326,6 +326,14 @@ public: template VTKM_CONT bool CanConvert() const; + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif ///@{ /// Returns this array cast appropriately and stored in the given `ArrayHandle` type. /// Throws an `ErrorBadType` if the stored array cannot be stored in the given array type. @@ -366,6 +374,9 @@ public: return array; } ///@} +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_END +#endif /// \brief Call a functor using the underlying array type. /// diff --git a/vtkm/cont/VariantArrayHandle.h b/vtkm/cont/VariantArrayHandle.h index 3d52aa0fb..03707de53 100644 --- a/vtkm/cont/VariantArrayHandle.h +++ b/vtkm/cont/VariantArrayHandle.h @@ -111,6 +111,14 @@ public: { } + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif /// Returns this array cast to the given \c ArrayHandle type. Throws \c /// ErrorBadType if the cast does not work. Use \c IsType /// to check if the cast can happen. @@ -120,6 +128,9 @@ public: { return this->AsArrayHandle(); } +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_END +#endif /// \brief Call a functor using the underlying array type. /// From 38630171900e86ca299d1fd6af6d74618ce662ec Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 3 Sep 2020 09:04:05 -0600 Subject: [PATCH 12/51] Test UnknownArrayHandle behavior on special arrays `UnknownArrayHandle` has special behavior when putting in or getting out an `ArrayHandleMultiplexer` or an `ArrayHandleCast`. When putting in either of these, `UnknownArrayHandle` gets the actual array stored in the multiplexer and cast so that you can later retrieve the base array. Likewise, when you get the array out with `AsArrayHandle`, you can give it an `ArrayHandleCast` or `ArrayHandleMultiplexer`, and you will get the base array placed inside of it. --- .../testing/UnitTestUnknownArrayHandle.cxx | 97 +++++++++++++++---- 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx index e581581e6..ceef14aee 100644 --- a/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx @@ -157,27 +157,86 @@ vtkm::cont::UnknownArrayHandle CreateArrayUnknown(T t) } template -void CheckCastToArrayHandle(const ArrayHandleType& array) +void CheckAsArrayHandle(const ArrayHandleType& array) { VTKM_IS_ARRAY_HANDLE(ArrayHandleType); + using T = typename ArrayHandleType::ValueType; vtkm::cont::UnknownArrayHandle arrayUnknown = array; VTKM_TEST_ASSERT(!arrayUnknown.IsType>(), "Dynamic array reporting is wrong type."); - ArrayHandleType castArray1; - arrayUnknown.AsArrayHandle(castArray1); - VTKM_TEST_ASSERT(arrayUnknown.CanConvert(), "Did not query handle correctly."); - VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array."); + { + std::cout << " Normal get ArrayHandle" << std::endl; + ArrayHandleType retreivedArray1; + arrayUnknown.AsArrayHandle(retreivedArray1); + VTKM_TEST_ASSERT(arrayUnknown.CanConvert(), "Did not query handle correctly."); + VTKM_TEST_ASSERT(array == retreivedArray1, "Did not get back same array."); - ArrayHandleType castArray2 = arrayUnknown.AsArrayHandle(); - VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array."); + ArrayHandleType retreivedArray2 = arrayUnknown.AsArrayHandle(); + VTKM_TEST_ASSERT(array == retreivedArray2, "Did not get back same array."); + } - vtkm::cont::UnknownArrayHandle arrayUnknown2 = vtkm::cont::ArrayHandleMultiplexer< - ArrayHandleType, - vtkm::cont::ArrayHandleConstant>(array); - VTKM_TEST_ASSERT(arrayUnknown2.IsType(), - "Putting in multiplexer did not pull out array."); + { + std::cout << " Put in cast array, get actual array" << std::endl; + auto castArray = vtkm::cont::make_ArrayHandleCast(array); + vtkm::cont::UnknownArrayHandle arrayUnknown2(castArray); + VTKM_TEST_ASSERT(arrayUnknown2.IsType()); + ArrayHandleType retrievedArray = arrayUnknown2.AsArrayHandle(); + VTKM_TEST_ASSERT(array == retrievedArray); + } + + { + std::cout << " Get array as cast" << std::endl; + vtkm::cont::ArrayHandleCast castArray; + arrayUnknown.AsArrayHandle(castArray); + VTKM_TEST_ASSERT(test_equal_portals(array.ReadPortal(), castArray.ReadPortal())); + } + + { + std::cout << " Put in multiplexer, get actual array" << std::endl; + vtkm::cont::UnknownArrayHandle arrayUnknown2 = vtkm::cont::ArrayHandleMultiplexer< + ArrayHandleType, + vtkm::cont::ArrayHandleConstant>(array); + VTKM_TEST_ASSERT(arrayUnknown2.IsType(), + "Putting in multiplexer did not pull out array."); + } + + { + std::cout << " Make sure multiplex array prefers direct array (1st arg)" << std::endl; + using MultiplexerType = + vtkm::cont::ArrayHandleMultiplexer>; + MultiplexerType multiplexArray = arrayUnknown.AsArrayHandle(); + + VTKM_TEST_ASSERT(multiplexArray.IsValid()); + VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 0); + VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), array.ReadPortal())); + } + + { + std::cout << " Make sure multiplex array prefers direct array (2nd arg)" << std::endl; + using MultiplexerType = + vtkm::cont::ArrayHandleMultiplexer>, + ArrayHandleType>; + MultiplexerType multiplexArray = arrayUnknown.AsArrayHandle(); + + VTKM_TEST_ASSERT(multiplexArray.IsValid()); + VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 1); + VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), array.ReadPortal())); + } + + { + std::cout << " Make sure adding arrays follows nesting of special arrays" << std::endl; + vtkm::cont::ArrayHandleMultiplexer, + vtkm::cont::ArrayHandleCast> + multiplexer(vtkm::cont::make_ArrayHandleCast(array)); + auto crazyArray = vtkm::cont::make_ArrayHandleCast(multiplexer); + vtkm::cont::UnknownArrayHandle arrayUnknown2(crazyArray); + VTKM_TEST_ASSERT(arrayUnknown2.IsType()); + ArrayHandleType retrievedArray = arrayUnknown2.AsArrayHandle(); + VTKM_TEST_ASSERT(array == retrievedArray); + } } // A vtkm::Vec if NumComps > 1, otherwise a scalar @@ -320,12 +379,12 @@ void TryUnusualType() } template -void TryCastToArrayHandle(const ArrayHandleType& array) +void TryAsArrayHandle(const ArrayHandleType& array) { - CheckCastToArrayHandle(array); + CheckAsArrayHandle(array); } -void TryCastToArrayHandle() +void TryAsArrayHandle() { std::cout << " Normal array handle." << std::endl; vtkm::Id buffer[ARRAY_SIZE]; @@ -336,10 +395,10 @@ void TryCastToArrayHandle() vtkm::cont::ArrayHandle array = vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE, vtkm::CopyFlag::On); - TryCastToArrayHandle(array); + TryAsArrayHandle(array); std::cout << " Constant array handle." << std::endl; - TryCastToArrayHandle(vtkm::cont::make_ArrayHandleConstant(5, ARRAY_SIZE)); + TryAsArrayHandle(vtkm::cont::make_ArrayHandleConstant(5, ARRAY_SIZE)); } void TrySetCastArray() @@ -386,8 +445,8 @@ void TestUnknownArrayHandle() std::cout << "Try unusual type." << std::endl; TryUnusualType(); - std::cout << "Try CastToArrayHandle" << std::endl; - TryCastToArrayHandle(); + std::cout << "Try AsArrayHandle" << std::endl; + TryAsArrayHandle(); std::cout << "Try setting ArrayHandleCast" << std::endl; TrySetCastArray(); From fb919e048e64ff7389263787f9a3484e1242f7f8 Mon Sep 17 00:00:00 2001 From: Vicente Adolfo Bolea Sanchez Date: Thu, 3 Sep 2020 16:10:15 -0400 Subject: [PATCH 13/51] vtkm::Vec: added unrolled arithmetic operators overload Signed-off-by: Vicente Adolfo Bolea Sanchez --- vtkm/Types.h | 198 +---- vtkm/internal/CMakeLists.txt | 2 + vtkm/internal/VecOperators.h | 1461 +++++++++++++++++++++++++++++++ vtkm/internal/VecOperators.h.in | 200 +++++ 4 files changed, 1666 insertions(+), 195 deletions(-) create mode 100644 vtkm/internal/VecOperators.h create mode 100644 vtkm/internal/VecOperators.h.in diff --git a/vtkm/Types.h b/vtkm/Types.h index b7d022668..6d5a82163 100644 --- a/vtkm/Types.h +++ b/vtkm/Types.h @@ -196,119 +196,15 @@ using FloatDefault = vtkm::Float64; using FloatDefault = vtkm::Float32; #endif + namespace internal { -//----------------------------------------------------------------------------- - /// Placeholder class for when a type is not applicable. -/// struct NullType { }; -//----------------------------------------------------------------------------- -template -struct VecComponentWiseUnaryOperation -{ - template - inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const - { - T result; - for (vtkm::IdComponent i = 0; i < Size; ++i) - { - result[i] = unaryOp(v[i]); - } - return result; - } -}; - -template <> -struct VecComponentWiseUnaryOperation<1> -{ - template - inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const - { - return T(unaryOp(v[0])); - } -}; - -template <> -struct VecComponentWiseUnaryOperation<2> -{ - template - inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const - { - return T(unaryOp(v[0]), unaryOp(v[1])); - } -}; - -template <> -struct VecComponentWiseUnaryOperation<3> -{ - template - inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const - { - return T(unaryOp(v[0]), unaryOp(v[1]), unaryOp(v[2])); - } -}; - -template <> -struct VecComponentWiseUnaryOperation<4> -{ - template - inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const - { - return T(unaryOp(v[0]), unaryOp(v[1]), unaryOp(v[2]), unaryOp(v[3])); - } -}; - -template -struct BindLeftBinaryOp -{ - // Warning: a reference. - const T& LeftValue; - const BinaryOpType BinaryOp; - VTKM_EXEC_CONT - BindLeftBinaryOp(const T& leftValue, BinaryOpType binaryOp = BinaryOpType()) - : LeftValue(leftValue) - , BinaryOp(binaryOp) - { - } - - template - VTKM_EXEC_CONT ReturnT operator()(const RightT& rightValue) const - { - return static_cast(this->BinaryOp(this->LeftValue, static_cast(rightValue))); - } - -private: - void operator=(const BindLeftBinaryOp&) = delete; -}; - -template -struct BindRightBinaryOp -{ - // Warning: a reference. - const T& RightValue; - const BinaryOpType BinaryOp; - VTKM_EXEC_CONT - BindRightBinaryOp(const T& rightValue, BinaryOpType binaryOp = BinaryOpType()) - : RightValue(rightValue) - , BinaryOp(binaryOp) - { - } - - template - VTKM_EXEC_CONT ReturnT operator()(const LeftT& leftValue) const - { - return static_cast(this->BinaryOp(static_cast(leftValue), this->RightValue)); - } - -private: - void operator=(const BindRightBinaryOp&) = delete; -}; - } // namespace internal // Disable conversion warnings for Add, Subtract, Multiply, Divide on GCC only. @@ -717,7 +613,6 @@ public: return this->Components[idx]; } - VTKM_SUPPRESS_EXEC_WARNINGS template inline VTKM_EXEC_CONT DerivedClass @@ -1664,94 +1559,6 @@ inline VTKM_EXEC_CONT T ReduceProduct(const vtkm::Vec& a) template struct Pair; -template -inline VTKM_EXEC_CONT vtkm::Vec operator*(T scalar, const vtkm::Vec& vec) -{ - return vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindLeftBinaryOp(scalar)); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator*(const vtkm::Vec& vec, T scalar) -{ - return vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindRightBinaryOp(scalar)); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator*(vtkm::Float64 scalar, - const vtkm::Vec& vec) -{ - return vtkm::Vec(vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindLeftBinaryOp(scalar))); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator*(const vtkm::Vec& vec, - vtkm::Float64 scalar) -{ - return vtkm::Vec(vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindRightBinaryOp(scalar))); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator*( - vtkm::Float64 scalar, - const vtkm::Vec& vec) -{ - return vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindLeftBinaryOp(scalar)); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator*( - const vtkm::Vec& vec, - vtkm::Float64 scalar) -{ - return vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindRightBinaryOp(scalar)); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator/(const vtkm::Vec& vec, T scalar) -{ - return vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindRightBinaryOp(scalar)); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator/(const vtkm::Vec& vec, - vtkm::Float64 scalar) -{ - return vtkm::Vec(vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindRightBinaryOp(scalar))); -} - -template -inline VTKM_EXEC_CONT vtkm::Vec operator/( - const vtkm::Vec& vec, - vtkm::Float64 scalar) -{ - return vtkm::internal::VecComponentWiseUnaryOperation()( - vec, vtkm::internal::BindRightBinaryOp(scalar)); -} - -// clang-format off -// The enable_if for this operator is effectively disabling the negate -// operator for Vec of unsigned integers. Another approach would be -// to use enable_if. That would be more inclusive but would -// also allow other types like Vec >. If necessary, we could -// change this implementation to be more inclusive. -template -inline VTKM_EXEC_CONT -typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), - vtkm::Vec>::type -operator-(const vtkm::Vec& x) -{ - return vtkm::internal::VecComponentWiseUnaryOperation()(x, vtkm::Negate()); -} -// clang-format on - /// Helper function for printing out vectors during testing. /// template @@ -1773,7 +1580,8 @@ inline VTKM_EXEC_CONT std::ostream& operator<<(std::ostream& stream, const vtkm: return stream << "[" << vec.first << "," << vec.second << "]"; } - } // End of namespace vtkm + +#include // Declared inside of vtkm namespace so that the operator work with ADL lookup #endif //vtk_m_Types_h diff --git a/vtkm/internal/CMakeLists.txt b/vtkm/internal/CMakeLists.txt index 2341dc389..f5523506f 100755 --- a/vtkm/internal/CMakeLists.txt +++ b/vtkm/internal/CMakeLists.txt @@ -74,6 +74,7 @@ set(headers Unreachable.h Variant.h VariantDetail.h + VecOperators.h Windows.h ) @@ -82,5 +83,6 @@ vtkm_declare_headers(${headers}) vtkm_pyexpander_generated_file(FunctionInterfaceDetailPre.h) vtkm_pyexpander_generated_file(FunctionInterfaceDetailPost.h) vtkm_pyexpander_generated_file(VariantDetail.h) +vtkm_pyexpander_generated_file(VecOperators.h) add_subdirectory(testing) diff --git a/vtkm/internal/VecOperators.h b/vtkm/internal/VecOperators.h new file mode 100644 index 000000000..4a3a930db --- /dev/null +++ b/vtkm/internal/VecOperators.h @@ -0,0 +1,1461 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +////////////////////////// **** DO NOT EDIT THIS FILE!!! **** +// This file is automatically generated by VecOperators.h.in +// clang-format off +#ifndef vtk_m_internal_VecOperators_h +#define vtk_m_internal_VecOperators_h + +#include + +namespace vtkm { + +#if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8))) +#if (defined(VTKM_GCC) || defined(VTKM_CLANG)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wfloat-conversion" +#endif // gcc || clang +#endif // not using cuda < 8 + +#if defined(VTKM_MSVC) +#pragma warning(push) +#pragma warning(disable : 4244) +#endif + + +// operator- unary overloads for generic and specific sizes {{{ +template +inline VTKM_EXEC_CONT +typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), + vtkm::Vec>::type +operator-(vtkm::Vec x) +{ + for(int i=0; i < Size; ++i) + { + x[i] = -x[i]; + } + return x; +} + +template +inline VTKM_EXEC_CONT +typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), + vtkm::Vec>::type +operator-(const vtkm::Vec& x) +{ + return vtkm::Vec(-x[0]); +} + +template +inline VTKM_EXEC_CONT +typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), + vtkm::Vec>::type +operator-(const vtkm::Vec& x) +{ + return vtkm::Vec(-x[0], -x[1]); +} + +template +inline VTKM_EXEC_CONT +typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), + vtkm::Vec>::type +operator-(const vtkm::Vec& x) +{ + return vtkm::Vec(-x[0], -x[1], -x[2]); +} + +template +inline VTKM_EXEC_CONT +typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), + vtkm::Vec>::type +operator-(const vtkm::Vec& x) +{ + return vtkm::Vec(-x[0], -x[1], -x[2], -x[3]); +} + + +//}}} + +// operator+ overloads for generic vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Vec a, const vtkm::Vec& b +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] + b[i]; + } + return a; +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Vec a, T scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] + scalar; + } + return a; +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] + scalar; + } + return a; +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] + scalar; + } + return a; +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + T scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar + a[i]; + } + return a; +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar + a[i]; + } + return a; +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar + a[i]; + } + return a; +} + +//}}} +// operator* overloads for generic vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Vec a, const vtkm::Vec& b +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] * b[i]; + } + return a; +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Vec a, T scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] * scalar; + } + return a; +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] * scalar; + } + return a; +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] * scalar; + } + return a; +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + T scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar * a[i]; + } + return a; +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar * a[i]; + } + return a; +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar * a[i]; + } + return a; +} + +//}}} +// operator- overloads for generic vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Vec a, const vtkm::Vec& b +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] - b[i]; + } + return a; +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Vec a, T scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] - scalar; + } + return a; +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] - scalar; + } + return a; +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] - scalar; + } + return a; +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + T scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar - a[i]; + } + return a; +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar - a[i]; + } + return a; +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar - a[i]; + } + return a; +} + +//}}} +// operator/ overloads for generic vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Vec a, const vtkm::Vec& b +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] / b[i]; + } + return a; +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Vec a, T scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] / scalar; + } + return a; +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] / scalar; + } + return a; +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Vec a, vtkm::Float64 scalar +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = a[i] / scalar; + } + return a; +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + T scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar / a[i]; + } + return a; +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar / a[i]; + } + return a; +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, vtkm::Vec a +) +{ + for (int i = 0; i < Size; ++i) + { + a[i] = scalar / a[i]; + } + return a; +} + +//}}} + +// operator+ overloads for specific vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] + b[0]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] + scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] + b[0], a[1] + b[1]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] + b[0], a[1] + b[1], a[2] + b[2]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar, a[2] + scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar, a[2] + scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar, a[2] + scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1], scalar + a[2]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1], scalar + a[2]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1], scalar + a[2]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar, a[2] + scalar, a[3] + scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar, a[2] + scalar, a[3] + scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] + scalar, a[1] + scalar, a[2] + scalar, a[3] + scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1], scalar + a[2], scalar + a[3]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1], scalar + a[2], scalar + a[3]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator+( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar + a[0], scalar + a[1], scalar + a[2], scalar + a[3]); +} + +//}}} +// operator* overloads for specific vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] * b[0]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] * scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] * b[0], a[1] * b[1]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] * b[0], a[1] * b[1], a[2] * b[2]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar, a[2] * scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar, a[2] * scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar, a[2] * scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1], scalar * a[2]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1], scalar * a[2]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1], scalar * a[2]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar, a[2] * scalar, a[3] * scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar, a[2] * scalar, a[3] * scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] * scalar, a[1] * scalar, a[2] * scalar, a[3] * scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1], scalar * a[2], scalar * a[3]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1], scalar * a[2], scalar * a[3]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator*( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar * a[0], scalar * a[1], scalar * a[2], scalar * a[3]); +} + +//}}} +// operator- overloads for specific vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] - b[0]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] - scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] - b[0], a[1] - b[1]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] - b[0], a[1] - b[1], a[2] - b[2]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar, a[2] - scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar, a[2] - scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar, a[2] - scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1], scalar - a[2]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1], scalar - a[2]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1], scalar - a[2]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar, a[2] - scalar, a[3] - scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar, a[2] - scalar, a[3] - scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] - scalar, a[1] - scalar, a[2] - scalar, a[3] - scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1], scalar - a[2], scalar - a[3]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1], scalar - a[2], scalar - a[3]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator-( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar - a[0], scalar - a[1], scalar - a[2], scalar - a[3]); +} + +//}}} +// operator/ overloads for specific vector sizes -------------------{{{ +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] / b[0]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] / scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] / b[0], a[1] / b[1]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] / b[0], a[1] / b[1], a[2] / b[2]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar, a[2] / scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar, a[2] / scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar, a[2] / scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1], scalar / a[2]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1], scalar / a[2]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1], scalar / a[2]); +} + +// Vec_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, const vtkm::Vec& b +) +{ + return vtkm::Vec(a[0] / b[0], a[1] / b[1], a[2] / b[2], a[3] / b[3]); +} + +// Vec_Scalar for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, T scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar, a[2] / scalar, a[3] / scalar); +} + +// Vec_Scalar for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar, a[2] / scalar, a[3] / scalar); +} + +// Vec_Scalar for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + const vtkm::Vec& a, vtkm::Float64 scalar +) +{ + return vtkm::Vec(a[0] / scalar, a[1] / scalar, a[2] / scalar, a[3] / scalar); +} + +// Scalar_Vec for ['T', 'T'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + T scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1], scalar / a[2], scalar / a[3]); +} + +// Scalar_Vec for ['T', 'vtkm::Float64'] +template +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1], scalar / a[2], scalar / a[3]); +} + +// Scalar_Vec for ['vtkm::Float64', 'vtkm::Float64'] +inline VTKM_EXEC_CONT vtkm::Vec operator/( + vtkm::Float64 scalar, const vtkm::Vec& a +) +{ + return vtkm::Vec(scalar / a[0], scalar / a[1], scalar / a[2], scalar / a[3]); +} + +//}}} + + +#if defined(VTKM_MSVC) +#pragma warning(pop) +#endif + +#if (defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8)) +#if (defined(VTKM_GCC) || defined(VTKM_CLANG)) +#pragma GCC diagnostic pop +#endif // gcc || clang +#endif // use cuda < 8 + +} + +// clang-format on +#endif //vtk_m_internal_VecOperators_h diff --git a/vtkm/internal/VecOperators.h.in b/vtkm/internal/VecOperators.h.in new file mode 100644 index 000000000..b66228e40 --- /dev/null +++ b/vtkm/internal/VecOperators.h.in @@ -0,0 +1,200 @@ +$# vim: ft=python.cpp foldmethod=marker +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +//$# This file uses the pyexpander macro processing utility to build the +//$# FunctionInterface facilities that use a variable number of arguments. +//$# Information, documentation, and downloads for pyexpander can be found at: +//$# +//$# http://pyexpander.sourceforge.net/ +//$# +//$# To build the source code, execute the following (after installing +//$# pyexpander, of course): +//$# +//$# expander.py VecOperators.h.in > VecOperators.h +//$# +//$# Ignore the following comment. It is meant for the generated file. +// **** DO NOT EDIT THIS FILE!!! **** +// This file is automatically generated by VecOperators.h.in +// clang-format off +#ifndef vtk_m_internal_VecOperators_h +#define vtk_m_internal_VecOperators_h + +#include + +namespace vtkm { + +#if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8))) +#if (defined(VTKM_GCC) || defined(VTKM_CLANG)) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wpragmas" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wfloat-conversion" +#endif // gcc || clang +#endif // not using cuda < 8 + +#if defined(VTKM_MSVC) +#pragma warning(push) +#pragma warning(disable : 4244) +#endif + + +$py( +max_size = 4 +operators = ['+', '*', '-', '/'] +operands = { + "Vec_Vec" : [['T', 'T']], + "Vec_Scalar" : [['T', 'T'], ['T', "vtkm::Float64"], ["vtkm::Float64", "vtkm::Float64"]], + "Scalar_Vec" : [['T', 'T'], ['T', "vtkm::Float64"], ["vtkm::Float64", "vtkm::Float64"]] +} +)\ +\ +// operator- unary overloads for generic and specific sizes {{{ +template +inline VTKM_EXEC_CONT +typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), + vtkm::Vec>::type +operator-(vtkm::Vec x) +{ + for(int i=0; i < Size; ++i) + { + x[i] = -x[i]; + } + return x; +} + +$for(SIZE in range(1, max_size+1))\ +template +inline VTKM_EXEC_CONT +typename std::enable_if<(std::is_floating_point::value || std::is_signed::value), + vtkm::Vec>::type +operator-(const vtkm::Vec& x) +{ + return vtkm::Vec(\ +$for(i in range(0, SIZE))\ +\ +$# Trailing comma between arguments +$if(i != 0)\ +, \ +$endif\ +\ +-x[$(i)]\ +\ +$endfor\ +); +} + +$endfor\ + +//}}} + +$for(OPERATOR in operators)\ +// operator$(OPERATOR) overloads for generic vector sizes -------------------{{{ +$for((PARAMETERS, types) in operands.items())\ +$for(TYPE in types)\ +\ +// $(PARAMETERS) for $(TYPE) +$if(TYPE[0] == "vtkm::Float64")\ +template +$else\ +template +$endif\ +inline VTKM_EXEC_CONT vtkm::Vec<$(TYPE[0]), Size> operator$(OPERATOR)( +$if(PARAMETERS == "Vec_Vec")\ + vtkm::Vec<$(TYPE[0]), Size> a, const vtkm::Vec<$(TYPE[1]), Size>& b +$elif(PARAMETERS == "Vec_Scalar")\ + vtkm::Vec<$(TYPE[0]), Size> a, $(TYPE[1]) scalar +$else\ + $(TYPE[1]) scalar, vtkm::Vec<$(TYPE[0]), Size> a +$endif\ +) +{ + for (int i = 0; i < Size; ++i) + { +$if(PARAMETERS == "Vec_Vec")\ + a[i] = a[i] $(OPERATOR) b[i]; +$elif(PARAMETERS == "Vec_Scalar")\ + a[i] = a[i] $(OPERATOR) scalar; +$else\ + a[i] = scalar $(OPERATOR) a[i]; +$endif\ + } + return a; +} + +$endfor\ +$endfor\ +//}}} +$endfor\ + +$for(OPERATOR in operators)\ +// operator$(OPERATOR) overloads for specific vector sizes -------------------{{{ +$for(SIZE in range(1, max_size+1))\ +$for((PARAMETERS, types) in operands.items())\ +$for(TYPE in types)\ +\ +// $(PARAMETERS) for $(TYPE) +$# No need for templates when all parameters are not templated +$if(TYPE[0] != "vtkm::Float64")\ +template +$endif\ +inline VTKM_EXEC_CONT vtkm::Vec<$(TYPE[0]), $(SIZE)> operator$(OPERATOR)( +$if(PARAMETERS == "Vec_Vec")\ + const vtkm::Vec<$(TYPE[0]), $(SIZE)>& a, const vtkm::Vec<$(TYPE[1]), $(SIZE)>& b +$elif(PARAMETERS == "Vec_Scalar")\ + const vtkm::Vec<$(TYPE[0]), $(SIZE)>& a, $(TYPE[1]) scalar +$else\ + $(TYPE[1]) scalar, const vtkm::Vec<$(TYPE[0]), $(SIZE)>& a +$endif\ +) +{ + return vtkm::Vec<$(TYPE[0]), $(SIZE)>(\ +$for(i in range(0, SIZE))\ +\ +$# Trailing comma between arguments +$if(i != 0)\ +, \ +$endif\ +\ +$if(PARAMETERS == "Vec_Vec")\ +a[$(i)] $(OPERATOR) b[$(i)]\ +\ +$elif(PARAMETERS == "Vec_Scalar")\ +a[$(i)] $(OPERATOR) scalar\ +\ +$else\ +scalar $(OPERATOR) a[$(i)]\ +\ +$endif\ +$endfor\ +); +} + +$endfor\ +$endfor\ +$endfor\ +//}}} +$endfor\ + + +#if defined(VTKM_MSVC) +#pragma warning(pop) +#endif + +#if (defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8)) +#if (defined(VTKM_GCC) || defined(VTKM_CLANG)) +#pragma GCC diagnostic pop +#endif // gcc || clang +#endif // use cuda < 8 + +} + +// clang-format on +#endif //vtk_m_internal_VecOperators_h From e11f612add3c8b3540d44fd7e7ce8c8f5bbc1ff3 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 2 Sep 2020 16:36:52 -0600 Subject: [PATCH 14/51] Deprecate ArrayHandleVirtual Virtual methods in the execution environment are going away the next major release of VTK-m, so deprecate their use in preparation for that. --- vtkm/cont/ArrayHandleVirtual.h | 4 +++- vtkm/cont/ArrayHandleVirtual.hxx | 4 ++++ vtkm/cont/ArrayRangeCompute.h | 10 ++++++---- vtkm/cont/StorageVirtual.h | 4 +++- vtkm/cont/StorageVirtual.hxx | 2 ++ vtkm/cont/VariantArrayHandle.h | 12 ++++++++++-- vtkm/cont/arg/TransportTagAtomicArray.h | 2 ++ vtkm/cont/arg/TypeCheckTagAtomicArray.h | 2 ++ vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx | 4 ++++ vtkm/cont/testing/UnitTestMoveConstructors.cxx | 11 ++++------- vtkm/cont/testing/UnitTestVariantArrayHandle.cxx | 2 ++ vtkm/filter/ContourTreeUniformAugmented.hxx | 2 +- vtkm/worklet/testing/UnitTestOrientNormals.cxx | 8 ++++---- 13 files changed, 47 insertions(+), 20 deletions(-) diff --git a/vtkm/cont/ArrayHandleVirtual.h b/vtkm/cont/ArrayHandleVirtual.h index 2e467f015..85faa14a6 100644 --- a/vtkm/cont/ArrayHandleVirtual.h +++ b/vtkm/cont/ArrayHandleVirtual.h @@ -26,8 +26,9 @@ namespace cont { +VTKM_DEPRECATED_SUPPRESS_BEGIN template -class VTKM_ALWAYS_EXPORT ArrayHandleVirtual +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6) ArrayHandleVirtual : public vtkm::cont::ArrayHandle { using StorageType = vtkm::cont::internal::Storage; @@ -267,6 +268,7 @@ VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Float64); #undef VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT #endif //vtk_m_cont_ArrayHandleVirtual_cxx +VTKM_DEPRECATED_SUPPRESS_END } } //namespace vtkm::cont diff --git a/vtkm/cont/ArrayHandleVirtual.hxx b/vtkm/cont/ArrayHandleVirtual.hxx index 2dd6386f3..d96e59ba0 100644 --- a/vtkm/cont/ArrayHandleVirtual.hxx +++ b/vtkm/cont/ArrayHandleVirtual.hxx @@ -13,6 +13,7 @@ #include #include +VTKM_DEPRECATED_SUPPRESS_BEGIN namespace vtkm { namespace cont @@ -37,6 +38,7 @@ ArrayHandleType inline ArrayHandleVirtual::CastToType( } } } // namespace vtkm::cont +VTKM_DEPRECATED_SUPPRESS_END #include @@ -45,6 +47,7 @@ ArrayHandleType inline ArrayHandleVirtual::CastToType( //============================================================================= // Specializations of serialization related classes /// @cond SERIALIZATION +VTKM_DEPRECATED_SUPPRESS_BEGIN namespace mangled_diy_namespace { @@ -178,5 +181,6 @@ struct Serialization> }; } // mangled_diy_namespace +VTKM_DEPRECATED_SUPPRESS_END #endif diff --git a/vtkm/cont/ArrayRangeCompute.h b/vtkm/cont/ArrayRangeCompute.h index 2a74a31a6..7ba24caf2 100644 --- a/vtkm/cont/ArrayRangeCompute.h +++ b/vtkm/cont/ArrayRangeCompute.h @@ -87,10 +87,12 @@ VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBas #undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T #undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC -VTKM_CONT -vtkm::cont::ArrayHandle ArrayRangeCompute( - const vtkm::cont::ArrayHandleVirtual& input, - vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()); +VTKM_DEPRECATED_SUPPRESS_BEGIN +VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual no longer supported.") + vtkm::cont::ArrayHandle ArrayRangeCompute( + const vtkm::cont::ArrayHandleVirtual& input, + vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()); +VTKM_DEPRECATED_SUPPRESS_END VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::ArrayHandle ArrayRangeCompute( const vtkm::cont::ArrayHandle class VTKM_ALWAYS_EXPORT Storage { @@ -315,6 +316,7 @@ private: { } }; +VTKM_DEPRECATED_SUPPRESS_END } // namespace internal } diff --git a/vtkm/cont/StorageVirtual.hxx b/vtkm/cont/StorageVirtual.hxx index ee436df82..80b9e4ade 100644 --- a/vtkm/cont/StorageVirtual.hxx +++ b/vtkm/cont/StorageVirtual.hxx @@ -235,6 +235,7 @@ void StorageVirtualImpl::TransferPortalForOutput( } } // namespace detail +VTKM_DEPRECATED_SUPPRESS_BEGIN template void Storage::Allocate(vtkm::Id numberOfValues) { @@ -433,6 +434,7 @@ struct ArrayTransfer : detail::ArrayTr return this->Superclass::PrepareForInPlace(Device()); } }; +VTKM_DEPRECATED_SUPPRESS_END } } } // namespace vtkm::cont::internal diff --git a/vtkm/cont/VariantArrayHandle.h b/vtkm/cont/VariantArrayHandle.h index 03707de53..7cf621e65 100644 --- a/vtkm/cont/VariantArrayHandle.h +++ b/vtkm/cont/VariantArrayHandle.h @@ -36,6 +36,7 @@ namespace internal namespace variant { +VTKM_DEPRECATED_SUPPRESS_BEGIN struct ForceCastToVirtual { template @@ -84,6 +85,7 @@ private: throw vtkm::cont::ErrorBadType(str.str()); } }; +VTKM_DEPRECATED_SUPPRESS_END } } // namespace internal::variant @@ -155,10 +157,12 @@ public: /// the CastAndCall. You can also specify a list of types to try as the optional /// third template argument. /// + VTKM_DEPRECATED_SUPPRESS_BEGIN template > - VTKM_CONT vtkm::cont::ArrayHandleVirtual AsVirtual() const + VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual is no longer supported.") + vtkm::cont::ArrayHandleVirtual AsVirtual() const { VTKM_IS_LIST(StorageList); VTKM_IS_LIST(TypeList); @@ -167,6 +171,7 @@ public: this->CastAndCall(caster, output); return output; } + VTKM_DEPRECATED_SUPPRESS_END /// Returns this array cast to a `ArrayHandleMultiplexer` of the given type. /// This will attempt to cast the internal array to each supported type of @@ -311,11 +316,14 @@ public: /// be specified in the second template parameter, which will be passed to /// the CastAndCall. /// + VTKM_DEPRECATED_SUPPRESS_BEGIN template - VTKM_CONT vtkm::cont::ArrayHandleVirtual AsVirtual() const + VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual is no longer suported.") + vtkm::cont::ArrayHandleVirtual AsVirtual() const { return this->Superclass::AsVirtual(); } + VTKM_DEPRECATED_SUPPRESS_END /// Changes the types to try casting to when resolving this variant array, /// which is specified with a list tag like those in TypeList.h. Since C++ diff --git a/vtkm/cont/arg/TransportTagAtomicArray.h b/vtkm/cont/arg/TransportTagAtomicArray.h index e78730575..d82449f66 100644 --- a/vtkm/cont/arg/TransportTagAtomicArray.h +++ b/vtkm/cont/arg/TransportTagAtomicArray.h @@ -64,6 +64,7 @@ struct Transport struct Transport, @@ -99,6 +100,7 @@ struct Transport::value; }; +VTKM_DEPRECATED_SUPPRESS_BEGIN template struct TypeCheck> { static constexpr bool value = vtkm::ListHas::value; }; +VTKM_DEPRECATED_SUPPRESS_END } } } // namespace vtkm::cont::arg diff --git a/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx b/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx index 084cca8b3..6a1917344 100644 --- a/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx +++ b/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx @@ -25,6 +25,8 @@ #include +VTKM_DEPRECATED_SUPPRESS_BEGIN + namespace UnitTestArrayHandleVirtualDetail { @@ -246,6 +248,8 @@ void TestArrayHandleVirtual() } // end namespace UnitTestArrayHandleVirtualDetail +VTKM_DEPRECATED_SUPPRESS_END + int UnitTestArrayHandleVirtual(int argc, char* argv[]) { using namespace UnitTestArrayHandleVirtualDetail; diff --git a/vtkm/cont/testing/UnitTestMoveConstructors.cxx b/vtkm/cont/testing/UnitTestMoveConstructors.cxx index d173053b4..cf3a03d4f 100644 --- a/vtkm/cont/testing/UnitTestMoveConstructors.cxx +++ b/vtkm/cont/testing/UnitTestMoveConstructors.cxx @@ -94,22 +94,22 @@ struct IsNoExceptHandle void operator()(T) const { using HandleType = vtkm::cont::ArrayHandle; - using VirtualType = vtkm::cont::ArrayHandleVirtual; + using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer; //verify the handle type is_noexcept_movable(); - is_noexcept_movable(); + is_noexcept_movable(); //verify the input portals of the handle is_noexcept_movable().PrepareForInput( vtkm::cont::DeviceAdapterTagSerial{}, std::declval()))>(); - is_noexcept_movable().PrepareForInput( + is_noexcept_movable().PrepareForInput( vtkm::cont::DeviceAdapterTagSerial{}, std::declval()))>(); //verify the output portals of the handle is_noexcept_movable().PrepareForOutput( 2, vtkm::cont::DeviceAdapterTagSerial{}, std::declval()))>(); - is_noexcept_movable().PrepareForOutput( + is_noexcept_movable().PrepareForOutput( 2, vtkm::cont::DeviceAdapterTagSerial{}, std::declval()))>(); } }; @@ -141,9 +141,6 @@ void TestContDataTypesHaveMoveSemantics() is_noexcept_movable(); is_noexcept_movable(); is_noexcept_movable(); - VTKM_DEPRECATED_SUPPRESS_BEGIN - is_noexcept_movable(); - VTKM_DEPRECATED_SUPPRESS_END //verify the CellSetStructured, and CellSetExplicit //have efficient storage in containers such as std::vector diff --git a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx index 98a74438b..18af83fe0 100644 --- a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx @@ -264,6 +264,7 @@ void CheckCastToVirtualArrayHandle(const ArrayType& array) VariantArrayType arrayVariant = array; + VTKM_DEPRECATED_SUPPRESS_BEGIN { auto testArray = arrayVariant.template AsVirtual(); VTKM_TEST_ASSERT(testArray.GetNumberOfValues() == array.GetNumberOfValues(), @@ -319,6 +320,7 @@ void CheckCastToVirtualArrayHandle(const ArrayType& array) VTKM_TEST_ASSERT(threw, "Casting to different vector width did not throw expected " "ErrorBadType exception."); + VTKM_DEPRECATED_SUPPRESS_END } template diff --git a/vtkm/filter/ContourTreeUniformAugmented.hxx b/vtkm/filter/ContourTreeUniformAugmented.hxx index 8799cce8b..665f02034 100644 --- a/vtkm/filter/ContourTreeUniformAugmented.hxx +++ b/vtkm/filter/ContourTreeUniformAugmented.hxx @@ -303,7 +303,7 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute( currBlock.GetField(this->GetActiveFieldName(), this->GetActiveFieldAssociation()); //const vtkm::cont::ArrayHandle &fieldData = currField.GetData().Cast >(); vtkm::cont::ArrayHandle fieldData; - vtkm::cont::ArrayCopy(currField.GetData().template AsVirtual(), fieldData); + vtkm::cont::ArrayCopy(currField.GetData().template ResetTypes>(), fieldData); auto currContourTreeMesh = vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper:: ComputeLocalContourTreeMesh( this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.LocalBlockOrigins.ReadPortal() diff --git a/vtkm/worklet/testing/UnitTestOrientNormals.cxx b/vtkm/worklet/testing/UnitTestOrientNormals.cxx index 490753940..dddd81de5 100644 --- a/vtkm/worklet/testing/UnitTestOrientNormals.cxx +++ b/vtkm/worklet/testing/UnitTestOrientNormals.cxx @@ -82,8 +82,8 @@ vtkm::cont::DataSet CreateDataSet(bool pointNormals, bool cellNormals) struct ValidateNormals { using CellSetType = vtkm::cont::CellSetSingleType<>; - using NormalType = vtkm::Vec; - using NormalsArrayType = vtkm::cont::ArrayHandleVirtual; + using NormalType = vtkm::Vec3f; + using NormalsArrayType = vtkm::cont::ArrayHandle; using NormalsPortalType = decltype(std::declval().ReadPortal()); using PointsType = decltype(std::declval().GetDataAsMultiplexer()); @@ -154,12 +154,12 @@ struct ValidateNormals if (this->CheckPoints) { - this->PointNormalsArray = pointNormalsField.GetData().AsVirtual(); + pointNormalsField.GetData().AsArrayHandle(this->PointNormalsArray); this->PointNormals = this->PointNormalsArray.ReadPortal(); } if (this->CheckCells) { - this->CellNormalsArray = cellNormalsField.GetData().AsVirtual(); + cellNormalsField.GetData().AsArrayHandle(this->CellNormalsArray); this->CellNormals = this->CellNormalsArray.ReadPortal(); } } From 63ef84ed781fec87edfb71d48f2c855afb435a57 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 3 Sep 2020 13:54:24 -0600 Subject: [PATCH 15/51] Optionally remove all use of ArrayHandleVirtual As we remove more and more virtual methods from VTK-m, I expect several users will be interested in completely removing them from the build for several reasons. 1. They may be compiling for hardware that does not support virtual methods. 2. They may need to compile for CUDA but need shared libraries. 3. It should go a bit faster. To enable this, a CMake option named `VTKm_NO_DEPRECATED_VIRTUAL` is added. It defaults to `OFF`. But when it is `ON`, none of the code that both uses virtuals and is deprecated will be built. Currently, only `ArrayHandleVirtual` is deprecated, so the rest of the virtual classes will still be built. As we move forward, more will be removed until all virtual method functionality is removed. --- CMakeLists.txt | 8 + benchmarking/BenchmarkFieldAlgorithms.cxx | 13 +- vtkm/cont/ArrayHandleCompositeVector.h | 9 +- vtkm/cont/ArrayHandleVirtual.h | 4 + vtkm/cont/ArrayHandleVirtualCoordinates.h | 4 + vtkm/cont/ArrayRangeCompute.h | 7 +- vtkm/cont/ArrayRangeCompute.hxx | 2 + vtkm/cont/CMakeLists.txt | 25 ++- vtkm/cont/CoordinateSystem.cxx | 11 ++ vtkm/cont/CoordinateSystem.h | 16 +- vtkm/cont/StorageVirtual.h | 4 + vtkm/cont/VariantArrayHandle.h | 11 +- vtkm/cont/arg/TransportTagAtomicArray.h | 5 + vtkm/cont/arg/TypeCheckTagAtomicArray.h | 8 +- vtkm/cont/cuda/testing/CMakeLists.txt | 1 - ...itTestCudaArrayHandleVirtualCoordinates.cu | 20 --- vtkm/cont/kokkos/testing/CMakeLists.txt | 1 - ...estKokkosArrayHandleVirtualCoordinates.cxx | 20 --- vtkm/cont/openmp/testing/CMakeLists.txt | 1 - ...estOpenMPArrayHandleVirtualCoordinates.cxx | 19 --- vtkm/cont/serial/testing/CMakeLists.txt | 1 - ...estSerialArrayHandleVirtualCoordinates.cxx | 21 --- vtkm/cont/tbb/testing/CMakeLists.txt | 1 - ...itTestTBBArrayHandleVirtualCoordinates.cxx | 20 --- vtkm/cont/testing/CMakeLists.txt | 1 - .../TestingArrayHandleVirtualCoordinates.h | 152 ------------------ .../testing/UnitTestArrayHandleVirtual.cxx | 11 ++ .../cont/testing/UnitTestMoveConstructors.cxx | 3 +- .../UnitTestSerializationArrayHandle.cxx | 1 - .../testing/UnitTestVariantArrayHandle.cxx | 11 +- vtkm/filter/Contour.h | 10 +- vtkm/filter/ContourInteger.cxx | 4 + vtkm/filter/ContourScalar.cxx | 4 + vtkm/filter/Gradient.h | 8 + vtkm/filter/GradientScalar.cxx | 4 + vtkm/filter/GradientVector.cxx | 4 + vtkm/internal/CMakeLists.txt | 2 + vtkm/internal/Configure.h.in | 3 + vtkm/io/testing/UnitTestVTKDataSetWriter.cxx | 2 + vtkm/worklet/Keys.h | 5 - vtkm/worklet/KeysSignedTypes.cxx | 4 - vtkm/worklet/KeysUnsignedTypes.cxx | 4 - vtkm/worklet/PointMerge.h | 3 +- .../worklet/testing/UnitTestOrientNormals.cxx | 1 - 44 files changed, 171 insertions(+), 298 deletions(-) delete mode 100644 vtkm/cont/cuda/testing/UnitTestCudaArrayHandleVirtualCoordinates.cu delete mode 100644 vtkm/cont/kokkos/testing/UnitTestKokkosArrayHandleVirtualCoordinates.cxx delete mode 100644 vtkm/cont/openmp/testing/UnitTestOpenMPArrayHandleVirtualCoordinates.cxx delete mode 100644 vtkm/cont/serial/testing/UnitTestSerialArrayHandleVirtualCoordinates.cxx delete mode 100644 vtkm/cont/tbb/testing/UnitTestTBBArrayHandleVirtualCoordinates.cxx delete mode 100644 vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 20fde1539..e907495f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,13 @@ vtkm_option(VTKm_ENABLE_DEVELOPER_FLAGS "Enable compiler flags that are useful w # Some application might need not to install those, hence this option. vtkm_option(VTKm_NO_INSTALL_README_LICENSE "disable the installation of README and LICENSE files" OFF) +# We are in the process of deprecating the use of virtual methods because they +# are not well supported on many accelerators. Turn this option on to remove +# the code entirely. Note that the deprecation of virtual methods is work in +# progress, so not all use of virtual methods may be done. In VTK-m 2.0 +# virtual methods should be removed entirely and this option will be removed. +vtkm_option(VTKm_NO_DEPRECATED_VIRTUAL "Do not compile support of deprecated virtual methods" OFF) + mark_as_advanced( VTKm_ENABLE_LOGGING VTKm_NO_ASSERT @@ -140,6 +147,7 @@ mark_as_advanced( VTKm_HIDE_PRIVATE_SYMBOLS VTKm_ENABLE_DEVELOPER_FLAGS VTKm_NO_INSTALL_README_LICENSE + VTKm_NO_DEPRECATED_VIRTUAL ) #----------------------------------------------------------------------------- diff --git a/benchmarking/BenchmarkFieldAlgorithms.cxx b/benchmarking/BenchmarkFieldAlgorithms.cxx index a0817f2ca..0228ecff4 100644 --- a/benchmarking/BenchmarkFieldAlgorithms.cxx +++ b/benchmarking/BenchmarkFieldAlgorithms.cxx @@ -13,13 +13,16 @@ #include #include -#include #include #include #include #include #include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#include +#endif + #include #include @@ -433,6 +436,7 @@ void BenchBlackScholesStatic(::benchmark::State& state) }; VTKM_BENCHMARK_TEMPLATES(BenchBlackScholesStatic, ValueTypes); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template void BenchBlackScholesDynamic(::benchmark::State& state) { @@ -442,6 +446,7 @@ void BenchBlackScholesDynamic(::benchmark::State& state) vtkm::cont::make_ArrayHandleVirtual(impl.OptionYears)); }; VTKM_BENCHMARK_TEMPLATES(BenchBlackScholesDynamic, ValueTypes); +#endif //VTKM_NO_DEPRECATED_VIRTUAL template void BenchBlackScholesMultiplexer0(::benchmark::State& state) @@ -537,6 +542,7 @@ void BenchMathStatic(::benchmark::State& state) }; VTKM_BENCHMARK_TEMPLATES(BenchMathStatic, ValueTypes); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template void BenchMathDynamic(::benchmark::State& state) { @@ -546,6 +552,7 @@ void BenchMathDynamic(::benchmark::State& state) vtkm::cont::make_ArrayHandleVirtual(impl.TempHandle2)); }; VTKM_BENCHMARK_TEMPLATES(BenchMathDynamic, ValueTypes); +#endif //VTKM_NO_DEPRECATED_VIRTUAL template void BenchMathMultiplexer0(::benchmark::State& state) @@ -636,6 +643,7 @@ void BenchFusedMathStatic(::benchmark::State& state) }; VTKM_BENCHMARK_TEMPLATES(BenchFusedMathStatic, ValueTypes); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template void BenchFusedMathDynamic(::benchmark::State& state) { @@ -643,6 +651,7 @@ void BenchFusedMathDynamic(::benchmark::State& state) impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.InputHandle)); }; VTKM_BENCHMARK_TEMPLATES(BenchFusedMathDynamic, ValueTypes); +#endif //VTKM_NO_DEPRECATED_VIRTUAL template void BenchFusedMathMultiplexer0(::benchmark::State& state) @@ -756,6 +765,7 @@ void BenchEdgeInterpStatic(::benchmark::State& state) }; VTKM_BENCHMARK_TEMPLATES(BenchEdgeInterpStatic, InterpValueTypes); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template void BenchEdgeInterpDynamic(::benchmark::State& state) { @@ -765,6 +775,7 @@ void BenchEdgeInterpDynamic(::benchmark::State& state) vtkm::cont::make_ArrayHandleVirtual(impl.FieldHandle)); }; VTKM_BENCHMARK_TEMPLATES(BenchEdgeInterpDynamic, InterpValueTypes); +#endif //VTKM_NO_DEPRECATED_VIRTUAL struct ImplicitFunctionBenchData { diff --git a/vtkm/cont/ArrayHandleCompositeVector.h b/vtkm/cont/ArrayHandleCompositeVector.h index 034a7dba1..cd7dd6090 100644 --- a/vtkm/cont/ArrayHandleCompositeVector.h +++ b/vtkm/cont/ArrayHandleCompositeVector.h @@ -67,13 +67,12 @@ struct AllAreArrayHandles // `vtkm::Vec`. This also validates that all members have the same `ValueType`. template -constexpr bool CheckValueType() +struct CheckValueType { VTKM_STATIC_ASSERT_MSG((std::is_same::value), "ArrayHandleCompositeVector must be built from " "ArrayHandles with the same ValueTypes."); - return std::is_same::value; -} +}; template struct GetValueType @@ -81,9 +80,7 @@ struct GetValueType static constexpr vtkm::IdComponent COUNT = static_cast(sizeof...(ArrayTypes)) + 1; using ComponentType = typename ArrayType0::ValueType; - static constexpr std::array ValueCheck{ - { true, CheckValueType()... } - }; + using ValueCheck = vtkm::List...>; using ValueType = vtkm::Vec; }; diff --git a/vtkm/cont/ArrayHandleVirtual.h b/vtkm/cont/ArrayHandleVirtual.h index 85faa14a6..7bb4a8210 100644 --- a/vtkm/cont/ArrayHandleVirtual.h +++ b/vtkm/cont/ArrayHandleVirtual.h @@ -20,6 +20,10 @@ #include +#ifdef VTKM_NO_DEPRECATED_VIRTUAL +#error "ArrayHandleVirtual is removed. Do not include ArrayHandleVirtual.h" +#endif + namespace vtkm { namespace cont diff --git a/vtkm/cont/ArrayHandleVirtualCoordinates.h b/vtkm/cont/ArrayHandleVirtualCoordinates.h index 83153a54b..64cf7454c 100644 --- a/vtkm/cont/ArrayHandleVirtualCoordinates.h +++ b/vtkm/cont/ArrayHandleVirtualCoordinates.h @@ -22,6 +22,10 @@ #include #include +#ifdef VTKM_NO_DEPRECATED_VIRTUAL +#error "ArrayHandleVirtualCoordiantes is removed. Do not include ArrayHandleVirtualCoordinates.h" +#endif + namespace vtkm { namespace cont diff --git a/vtkm/cont/ArrayRangeCompute.h b/vtkm/cont/ArrayRangeCompute.h index 7ba24caf2..6781a4042 100644 --- a/vtkm/cont/ArrayRangeCompute.h +++ b/vtkm/cont/ArrayRangeCompute.h @@ -16,9 +16,12 @@ #include #include #include -#include #include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#include +#endif + namespace vtkm { namespace cont @@ -87,12 +90,14 @@ VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBas #undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T #undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC +#ifndef VTKM_NO_DEPRECATED_VIRTUAL VTKM_DEPRECATED_SUPPRESS_BEGIN VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual no longer supported.") vtkm::cont::ArrayHandle ArrayRangeCompute( const vtkm::cont::ArrayHandleVirtual& input, vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny()); VTKM_DEPRECATED_SUPPRESS_END +#endif //VTKM_NO_DEPRECATED_VIRTUAL VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::ArrayHandle ArrayRangeCompute( const vtkm::cont::ArrayHandle ArrayRangeComputeImpl( } // namespace detail +#ifndef VTKM_NO_DEPRECATED_VIRTUAL VTKM_CONT inline vtkm::cont::ArrayHandle ArrayRangeCompute( const vtkm::cont::ArrayHandleVirtual& input, @@ -132,6 +133,7 @@ inline vtkm::cont::ArrayHandle ArrayRangeCompute( return detail::ArrayRangeComputeImpl(input, device); } } +#endif //VTKM_NO_DEPRECATED_VIRTUAL template inline vtkm::cont::ArrayHandle ArrayRangeCompute(const ArrayHandleType& input, diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index 602225369..2a50baf52 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -41,8 +41,6 @@ set(headers ArrayHandleTransform.h ArrayHandleUniformPointCoordinates.h ArrayHandleView.h - ArrayHandleVirtual.h - ArrayHandleVirtualCoordinates.h ArrayHandleZip.h ArrayPortal.h ArrayPortalToIterators.h @@ -111,7 +109,6 @@ set(headers StorageImplicit.h StorageList.h StorageListTag.h - StorageVirtual.h Timer.h Token.h TryExecute.h @@ -124,7 +121,6 @@ set(headers set(template_sources ArrayHandle.hxx - ArrayHandleVirtual.hxx ArrayRangeCompute.hxx CellSetExplicit.hxx CellSetExtrude.hxx @@ -133,7 +129,6 @@ set(template_sources FieldRangeCompute.hxx FieldRangeGlobalCompute.hxx ParticleArrayCopy.hxx - StorageVirtual.hxx VirtualObjectHandle.hxx ) @@ -162,7 +157,6 @@ set(sources # This list of sources has code that uses devices and so might need to be # compiled with a device-specific compiler (like CUDA). set(device_sources - ArrayHandleVirtual.cxx ArrayRangeCompute.cxx AssignerPartitionedDataSet.cxx BoundsCompute.cxx @@ -190,11 +184,28 @@ set(sources PointLocator.cxx PointLocatorUniformGrid.cxx RuntimeDeviceInformation.cxx - StorageVirtual.cxx Timer.cxx UnknownArrayHandle.cxx ) +if (NOT VTKm_NO_DEPRECATED_VIRTUAL) + set(headers ${headers} + ArrayHandleVirtual.h + ArrayHandleVirtualCoordinates.h + StorageVirtual.h + ) + + set(template_sources ${template_sources} + ArrayHandleVirtual.hxx + StorageVirtual.hxx + ) + + set(device_sources ${device_sources} + ArrayHandleVirtual.cxx + StorageVirtual.cxx + ) +endif() + #----------------------------------------------------------------------------- # Set up default types, which can be custom configured by other build systems. vtkm_get_kit_name(kit_name kit_dir) diff --git a/vtkm/cont/CoordinateSystem.cxx b/vtkm/cont/CoordinateSystem.cxx index 271b85f13..64eac00de 100644 --- a/vtkm/cont/CoordinateSystem.cxx +++ b/vtkm/cont/CoordinateSystem.cxx @@ -16,6 +16,7 @@ namespace vtkm namespace cont { +#ifndef VTKM_NO_DEPRECATED_VIRTUAL namespace detail { @@ -27,6 +28,7 @@ vtkm::cont::ArrayHandleVirtualCoordinates CoordDataDepWrapper::ToArray() const VTKM_DEPRECATED_SUPPRESS_END } // namespace detail +#endif //VTKM_NO_DEPRECATED_VIRTUAL VTKM_CONT CoordinateSystem::CoordinateSystem() : Superclass() @@ -52,10 +54,19 @@ CoordinateSystem::CoordinateSystem(std::string name, { } +#ifndef VTKM_NO_DEPRECATED_VIRTUAL VTKM_CONT vtkm::cont::detail::CoordDataDepWrapper CoordinateSystem::GetData() const { return vtkm::cont::detail::CoordDataDepWrapper(this->Superclass::GetData()); } +#else //!VTKM_NO_DEPRECATED_VIRTUAL +VTKM_CONT vtkm::cont::VariantArrayHandleBase CoordinateSystem::GetData() + const +{ + return vtkm::cont::VariantArrayHandleBase(this->Superclass::GetData()); +} +#endif //!VTKM_NO_DEPRECATED_VIRTUAL + VTKM_CONT vtkm::cont::CoordinateSystem::MultiplexerArrayType CoordinateSystem::GetDataAsMultiplexer() const diff --git a/vtkm/cont/CoordinateSystem.h b/vtkm/cont/CoordinateSystem.h index 7ad9c5e21..1d007e4b3 100644 --- a/vtkm/cont/CoordinateSystem.h +++ b/vtkm/cont/CoordinateSystem.h @@ -14,15 +14,19 @@ #include #include -#include #include #include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#include +#endif + namespace vtkm { namespace cont { +#ifndef VTKM_NO_DEPRECATED_VIRTUAL namespace detail { @@ -117,6 +121,7 @@ VTKM_CONT VTKM_DEPRECATED( vtkm::cont::printSummary_ArrayHandle(coordArray, out, full); } VTKM_DEPRECATED_SUPPRESS_END +#endif //VTKM_NO_DEPRECATED_VIRTUAL class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field { @@ -146,7 +151,11 @@ public: VTKM_CONT vtkm::Id GetNumberOfPoints() const { return this->GetNumberOfValues(); } +#ifndef VTKM_NO_DEPRECATED_VIRTUAL VTKM_CONT detail::CoordDataDepWrapper GetData() const; +#else + VTKM_CONT vtkm::cont::VariantArrayHandleBase GetData() const; +#endif private: #ifdef VTKM_USE_DOUBLE_PRECISION @@ -267,11 +276,14 @@ struct DynamicTransformTraits using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; }; +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template <> struct DynamicTransformTraits { using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; }; +#endif //VTKM_NO_DEPRECATED_VIRTUAL + } // namespace internal } // namespace cont @@ -283,12 +295,14 @@ struct DynamicTransformTraits namespace mangled_diy_namespace { +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template <> struct Serialization : public Serialization< vtkm::cont::VariantArrayHandleBase>> { }; +#endif //VTKM_NO_DEPRECATED_VIRTUAL template <> struct Serialization diff --git a/vtkm/cont/StorageVirtual.h b/vtkm/cont/StorageVirtual.h index 7d1ece430..5212d421d 100644 --- a/vtkm/cont/StorageVirtual.h +++ b/vtkm/cont/StorageVirtual.h @@ -20,6 +20,10 @@ #include +#ifdef VTKM_NO_DEPRECATED_VIRTUAL +#error "ArrayHandleVirtual is removed. Do not include StorageVirtual.h" +#endif + namespace vtkm { namespace cont diff --git a/vtkm/cont/VariantArrayHandle.h b/vtkm/cont/VariantArrayHandle.h index 7cf621e65..58999a157 100644 --- a/vtkm/cont/VariantArrayHandle.h +++ b/vtkm/cont/VariantArrayHandle.h @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -26,11 +25,16 @@ #include #include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#include +#endif //VTKM_NO_DEPRECATED_VIRTUAL + namespace vtkm { namespace cont { +#ifndef VTKM_NO_DEPRECATED_VIRTUAL namespace internal { namespace variant @@ -89,6 +93,7 @@ VTKM_DEPRECATED_SUPPRESS_END } } // namespace internal::variant +#endif //VTKM_NO_DEPRECATED_VIRTUAL /// \brief VariantArrayHandle superclass holding common operations. /// @@ -148,6 +153,7 @@ public: std::forward(args)...); } +#ifndef VTKM_NO_DEPRECATED_VIRTUAL /// Returns this array cast to a `ArrayHandleVirtual` of the given type. /// This will perform type conversions as necessary, and will log warnings /// if the conversion is lossy. @@ -172,6 +178,7 @@ public: return output; } VTKM_DEPRECATED_SUPPRESS_END +#endif //VTKM_NO_DEPRECATED_VIRTUAL /// Returns this array cast to a `ArrayHandleMultiplexer` of the given type. /// This will attempt to cast the internal array to each supported type of @@ -308,6 +315,7 @@ public: } +#ifndef VTKM_NO_DEPRECATED_VIRTUAL /// Returns this array cast to a \c ArrayHandleVirtual of the given type. /// This will perform type conversions as necessary, and will log warnings /// if the conversion is lossy. @@ -324,6 +332,7 @@ public: return this->Superclass::AsVirtual(); } VTKM_DEPRECATED_SUPPRESS_END +#endif //VTKM_NO_DEPRECATED_VIRTUAL /// Changes the types to try casting to when resolving this variant array, /// which is specified with a list tag like those in TypeList.h. Since C++ diff --git a/vtkm/cont/arg/TransportTagAtomicArray.h b/vtkm/cont/arg/TransportTagAtomicArray.h index d82449f66..90d832c62 100644 --- a/vtkm/cont/arg/TransportTagAtomicArray.h +++ b/vtkm/cont/arg/TransportTagAtomicArray.h @@ -13,8 +13,11 @@ #include #include + +#ifndef VTKM_NO_DEPRECATED_VIRTUAL #include #include +#endif #include @@ -64,6 +67,7 @@ struct Transport struct Transport #include -#include - #include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#include +#endif //VTKM_NO_DEPRECATED_VIRTUAL + namespace vtkm { namespace cont @@ -44,6 +46,7 @@ struct TypeCheck::value; }; +#ifndef VTKM_NO_DEPRECATED_VIRTUAL VTKM_DEPRECATED_SUPPRESS_BEGIN template struct TypeCheck> @@ -51,6 +54,7 @@ struct TypeCheck::value; }; VTKM_DEPRECATED_SUPPRESS_END +#endif //VTKM_NO_DEPRECATED_VIRTUAL } } } // namespace vtkm::cont::arg diff --git a/vtkm/cont/cuda/testing/CMakeLists.txt b/vtkm/cont/cuda/testing/CMakeLists.txt index f2f4874fd..b23f65c5a 100644 --- a/vtkm/cont/cuda/testing/CMakeLists.txt +++ b/vtkm/cont/cuda/testing/CMakeLists.txt @@ -12,7 +12,6 @@ set(unit_tests UnitTestCudaArrayHandle.cu UnitTestCudaArrayHandleFancy.cu UnitTestCudaArrayHandleMultiplexer.cu - UnitTestCudaArrayHandleVirtualCoordinates.cu UnitTestCudaBitField.cu UnitTestCudaCellLocatorRectilinearGrid.cu UnitTestCudaCellLocatorUniformBins.cu diff --git a/vtkm/cont/cuda/testing/UnitTestCudaArrayHandleVirtualCoordinates.cu b/vtkm/cont/cuda/testing/UnitTestCudaArrayHandleVirtualCoordinates.cu deleted file mode 100644 index a1b2d830f..000000000 --- a/vtkm/cont/cuda/testing/UnitTestCudaArrayHandleVirtualCoordinates.cu +++ /dev/null @@ -1,20 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ - -#include -#include - -int UnitTestCudaArrayHandleVirtualCoordinates(int argc, char* argv[]) -{ - auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); - tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{}); - return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates< - vtkm::cont::DeviceAdapterTagCuda>::Run(argc, argv); -} diff --git a/vtkm/cont/kokkos/testing/CMakeLists.txt b/vtkm/cont/kokkos/testing/CMakeLists.txt index 524821c92..a40f93048 100644 --- a/vtkm/cont/kokkos/testing/CMakeLists.txt +++ b/vtkm/cont/kokkos/testing/CMakeLists.txt @@ -12,7 +12,6 @@ set(unit_tests UnitTestKokkosArrayHandle.cxx UnitTestKokkosArrayHandleFancy.cxx UnitTestKokkosArrayHandleMultiplexer.cxx - UnitTestKokkosArrayHandleVirtualCoordinates.cxx UnitTestKokkosBitField.cxx UnitTestKokkosCellLocatorRectilinearGrid.cxx UnitTestKokkosCellLocatorUniformBins.cxx diff --git a/vtkm/cont/kokkos/testing/UnitTestKokkosArrayHandleVirtualCoordinates.cxx b/vtkm/cont/kokkos/testing/UnitTestKokkosArrayHandleVirtualCoordinates.cxx deleted file mode 100644 index 51732807c..000000000 --- a/vtkm/cont/kokkos/testing/UnitTestKokkosArrayHandleVirtualCoordinates.cxx +++ /dev/null @@ -1,20 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ - -#include -#include - -int UnitTestKokkosArrayHandleVirtualCoordinates(int argc, char* argv[]) -{ - auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); - tracker.ForceDevice(vtkm::cont::DeviceAdapterTagKokkos{}); - return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates< - vtkm::cont::DeviceAdapterTagKokkos>::Run(argc, argv); -} diff --git a/vtkm/cont/openmp/testing/CMakeLists.txt b/vtkm/cont/openmp/testing/CMakeLists.txt index 1b6f69bf9..2f3c4af2f 100644 --- a/vtkm/cont/openmp/testing/CMakeLists.txt +++ b/vtkm/cont/openmp/testing/CMakeLists.txt @@ -12,7 +12,6 @@ set(unit_tests UnitTestOpenMPArrayHandle.cxx UnitTestOpenMPArrayHandleFancy.cxx UnitTestOpenMPArrayHandleMultiplexer.cxx - UnitTestOpenMPArrayHandleVirtualCoordinates.cxx UnitTestOpenMPBitField.cxx UnitTestOpenMPCellLocatorRectilinearGrid.cxx UnitTestOpenMPCellLocatorUniformBins.cxx diff --git a/vtkm/cont/openmp/testing/UnitTestOpenMPArrayHandleVirtualCoordinates.cxx b/vtkm/cont/openmp/testing/UnitTestOpenMPArrayHandleVirtualCoordinates.cxx deleted file mode 100644 index ab7c8bbbe..000000000 --- a/vtkm/cont/openmp/testing/UnitTestOpenMPArrayHandleVirtualCoordinates.cxx +++ /dev/null @@ -1,19 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ -#include -#include - -int UnitTestOpenMPArrayHandleVirtualCoordinates(int argc, char* argv[]) -{ - auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); - tracker.ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{}); - return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates< - vtkm::cont::DeviceAdapterTagOpenMP>::Run(argc, argv); -} diff --git a/vtkm/cont/serial/testing/CMakeLists.txt b/vtkm/cont/serial/testing/CMakeLists.txt index e19eaa301..787a2631b 100644 --- a/vtkm/cont/serial/testing/CMakeLists.txt +++ b/vtkm/cont/serial/testing/CMakeLists.txt @@ -12,7 +12,6 @@ set(unit_tests UnitTestSerialArrayHandle.cxx UnitTestSerialArrayHandleFancy.cxx UnitTestSerialArrayHandleMultiplexer.cxx - UnitTestSerialArrayHandleVirtualCoordinates.cxx UnitTestSerialBitField.cxx UnitTestSerialCellLocatorRectilinearGrid.cxx UnitTestSerialCellLocatorUniformBins.cxx diff --git a/vtkm/cont/serial/testing/UnitTestSerialArrayHandleVirtualCoordinates.cxx b/vtkm/cont/serial/testing/UnitTestSerialArrayHandleVirtualCoordinates.cxx deleted file mode 100644 index a01a70b7d..000000000 --- a/vtkm/cont/serial/testing/UnitTestSerialArrayHandleVirtualCoordinates.cxx +++ /dev/null @@ -1,21 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ - -#include -#include -#include - -int UnitTestSerialArrayHandleVirtualCoordinates(int argc, char* argv[]) -{ - auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); - tracker.ForceDevice(vtkm::cont::DeviceAdapterTagSerial{}); - return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates< - vtkm::cont::DeviceAdapterTagSerial>::Run(argc, argv); -} diff --git a/vtkm/cont/tbb/testing/CMakeLists.txt b/vtkm/cont/tbb/testing/CMakeLists.txt index 8868478b6..ed484b9b9 100644 --- a/vtkm/cont/tbb/testing/CMakeLists.txt +++ b/vtkm/cont/tbb/testing/CMakeLists.txt @@ -12,7 +12,6 @@ set(unit_tests UnitTestTBBArrayHandle.cxx UnitTestTBBArrayHandleFancy.cxx UnitTestTBBArrayHandleMultiplexer.cxx - UnitTestTBBArrayHandleVirtualCoordinates.cxx UnitTestTBBBitField.cxx UnitTestTBBCellLocatorRectilinearGrid.cxx UnitTestTBBCellLocatorUniformBins.cxx diff --git a/vtkm/cont/tbb/testing/UnitTestTBBArrayHandleVirtualCoordinates.cxx b/vtkm/cont/tbb/testing/UnitTestTBBArrayHandleVirtualCoordinates.cxx deleted file mode 100644 index 877a1c086..000000000 --- a/vtkm/cont/tbb/testing/UnitTestTBBArrayHandleVirtualCoordinates.cxx +++ /dev/null @@ -1,20 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ - -#include -#include - -int UnitTestTBBArrayHandleVirtualCoordinates(int argc, char* argv[]) -{ - auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); - tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{}); - return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates< - vtkm::cont::DeviceAdapterTagTBB>::Run(argc, argv); -} diff --git a/vtkm/cont/testing/CMakeLists.txt b/vtkm/cont/testing/CMakeLists.txt index e5a9718b9..38ec5ac03 100644 --- a/vtkm/cont/testing/CMakeLists.txt +++ b/vtkm/cont/testing/CMakeLists.txt @@ -14,7 +14,6 @@ set(headers Testing.h TestingArrayHandles.h TestingArrayHandleMultiplexer.h - TestingArrayHandleVirtualCoordinates.h TestingCellLocatorRectilinearGrid.h TestingCellLocatorUniformBins.h TestingCellLocatorUniformGrid.h diff --git a/vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h b/vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h deleted file mode 100644 index f80013fbb..000000000 --- a/vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h +++ /dev/null @@ -1,152 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ -#ifndef vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h -#define vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h - -// This is testing deprecated functionality. It is left to make sure that old code -// still works, but will be removed if ArrayHandleVirtualCoordinates is removed. - -#include -#include -#include -#include -#include -#include - -VTKM_DEPRECATED_SUPPRESS_BEGIN - -namespace vtkm -{ -namespace cont -{ -namespace testing -{ - -namespace -{ - -struct CopyWorklet : public vtkm::worklet::WorkletMapField -{ - using ControlSignature = void(FieldIn in, FieldOut out); - using ExecutionSignature = _2(_1); - - template - VTKM_EXEC T operator()(const T& in) const - { - return in; - } -}; - -// A dummy worklet -struct DoubleWorklet : public vtkm::worklet::WorkletMapField -{ - typedef void ControlSignature(FieldIn in); - typedef void ExecutionSignature(_1); - using InputDomain = _1; - - template - VTKM_EXEC void operator()(T& in) const - { - in = in * 2; - } -}; - -template -inline void TestVirtualAccess(const vtkm::cont::ArrayHandle& in, - vtkm::cont::ArrayHandle& out) -{ - vtkm::worklet::DispatcherMapField().Invoke( - vtkm::cont::ArrayHandleVirtualCoordinates(in), vtkm::cont::ArrayHandleVirtualCoordinates(out)); - - VTKM_TEST_ASSERT(test_equal_portals(in.ReadPortal(), out.ReadPortal()), - "Input and output portals don't match"); -} - - -} // anonymous namespace - -template -class TestingArrayHandleVirtualCoordinates -{ -private: - using ArrayHandleRectilinearCoords = - vtkm::cont::ArrayHandleCartesianProduct, - vtkm::cont::ArrayHandle, - vtkm::cont::ArrayHandle>; - - - - static void TestAll() - { - using PointType = vtkm::Vec3f; - static constexpr vtkm::Id length = 64; - - vtkm::cont::ArrayHandle out; - - std::cout << "Testing basic ArrayHandle as input\n"; - vtkm::cont::ArrayHandle a1; - a1.Allocate(length); - for (vtkm::Id i = 0; i < length; ++i) - { - a1.WritePortal().Set(i, TestValue(i, PointType())); - } - TestVirtualAccess(a1, out); - - std::cout << "Testing ArrayHandleUniformPointCoordinates as input\n"; - auto t = vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(4, 4, 4)); - TestVirtualAccess(t, out); - - std::cout << "Testing ArrayHandleCartesianProduct as input\n"; - vtkm::cont::ArrayHandle c1, c2, c3; - c1.Allocate(length); - c2.Allocate(length); - c3.Allocate(length); - auto portal = a1.ReadPortal(); - for (vtkm::Id i = 0; i < length; ++i) - { - auto p = portal.Get(i); - c1.WritePortal().Set(i, p[0]); - c2.WritePortal().Set(i, p[1]); - c3.WritePortal().Set(i, p[2]); - } - TestVirtualAccess(vtkm::cont::make_ArrayHandleCartesianProduct(c1, c2, c3), out); - - std::cout << "Testing resources releasing on ArrayHandleVirtualCoordinates\n"; - vtkm::cont::ArrayHandleVirtualCoordinates virtualC = - vtkm::cont::ArrayHandleVirtualCoordinates(a1); - vtkm::worklet::DispatcherMapField().Invoke(a1); - virtualC.ReleaseResourcesExecution(); - VTKM_TEST_ASSERT(a1.GetNumberOfValues() == length, - "ReleaseResourcesExecution" - " should not change the number of values on the Arrayhandle"); - VTKM_TEST_ASSERT( - virtualC.GetNumberOfValues() == length, - "ReleaseResources" - " should set the number of values on the ArrayHandleVirtualCoordinates to be 0"); - virtualC.ReleaseResources(); - VTKM_TEST_ASSERT(a1.GetNumberOfValues() == 0, - "ReleaseResources" - " should set the number of values on the Arrayhandle to be 0"); - } - -public: - static int Run(int argc, char* argv[]) - { - vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(DeviceAdapter()); - return vtkm::cont::testing::Testing::Run(TestAll, argc, argv); - } -}; -} -} -} // vtkm::cont::testing - -VTKM_DEPRECATED_SUPPRESS_END - -#endif // vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h diff --git a/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx b/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx index 6a1917344..f1a71a6cf 100644 --- a/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx +++ b/vtkm/cont/testing/UnitTestArrayHandleVirtual.cxx @@ -10,8 +10,11 @@ #include #include + +#ifndef VTKM_NO_DEPRECATED_VIRTUAL #include #include +#endif #include @@ -25,6 +28,7 @@ #include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL VTKM_DEPRECATED_SUPPRESS_BEGIN namespace UnitTestArrayHandleVirtualDetail @@ -249,9 +253,16 @@ void TestArrayHandleVirtual() } // end namespace UnitTestArrayHandleVirtualDetail VTKM_DEPRECATED_SUPPRESS_END +#endif //VTKM_NO_DEPRECATED_VIRTUAL int UnitTestArrayHandleVirtual(int argc, char* argv[]) { +#ifndef VTKM_NO_DEPRECATED_VIRTUAL using namespace UnitTestArrayHandleVirtualDetail; return vtkm::cont::testing::Testing::Run(TestArrayHandleVirtual, argc, argv); +#else + (void)argc; + (void)argv; + return 0; +#endif } diff --git a/vtkm/cont/testing/UnitTestMoveConstructors.cxx b/vtkm/cont/testing/UnitTestMoveConstructors.cxx index cf3a03d4f..a932be419 100644 --- a/vtkm/cont/testing/UnitTestMoveConstructors.cxx +++ b/vtkm/cont/testing/UnitTestMoveConstructors.cxx @@ -8,7 +8,6 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ #include -#include #include #include @@ -136,7 +135,7 @@ void TestContDataTypesHaveMoveSemantics() vtkm::testing::Testing::TryTypes(IsNoExceptHandle{}, ::vtkmComplexCustomTypes{}); - //verify the DataSet, Field, CoordinateSystem, and ArrayHandleVirtualCoordinates + //verify the DataSet, Field, and CoordinateSystem //all have efficient storage in containers such as std::vector is_noexcept_movable(); is_noexcept_movable(); diff --git a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx index 6307dda58..86b8449a6 100644 --- a/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestSerializationArrayHandle.cxx @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx index 18af83fe0..f954f59e6 100644 --- a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx @@ -22,9 +22,12 @@ #include #include #include -#include #include +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#include +#endif + #include #include @@ -114,6 +117,7 @@ struct CheckFunctor CheckArray(array); } +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template void operator()(const vtkm::cont::ArrayHandleVirtual& array, bool& vtkmNotUsed(calledBasic), @@ -124,6 +128,7 @@ struct CheckFunctor CheckArray(array); } +#endif //VTKM_NO_DEPRECATED_VIRTUAL template void operator()(const vtkm::cont::ArrayHandle&, bool&, bool&) const @@ -246,6 +251,7 @@ void CheckCastToArrayHandle(const ArrayHandleType& array) template using VecOrScalar = typename std::conditional<(NumComps > 1), vtkm::Vec, T>::type; +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template void CheckCastToVirtualArrayHandle(const ArrayType& array) { @@ -322,6 +328,7 @@ void CheckCastToVirtualArrayHandle(const ArrayType& array) "ErrorBadType exception."); VTKM_DEPRECATED_SUPPRESS_END } +#endif //VTKM_NO_DEPRECATED_VIRTUAL template void TryNewInstance(T, ArrayVariantType originalArray) @@ -453,7 +460,9 @@ template void TryCastToArrayHandle(const ArrayHandleType& array) { CheckCastToArrayHandle(array); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL CheckCastToVirtualArrayHandle(array); +#endif } void TryCastToArrayHandle() diff --git a/vtkm/filter/Contour.h b/vtkm/filter/Contour.h index 120319bc8..6bf23a061 100644 --- a/vtkm/filter/Contour.h +++ b/vtkm/filter/Contour.h @@ -181,11 +181,13 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, @@ -193,11 +195,13 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, @@ -205,11 +209,13 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, @@ -217,13 +223,15 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); - #endif + +#endif //!vtkm_filter_ContourExecute_cxx } } // namespace vtkm::filter diff --git a/vtkm/filter/ContourInteger.cxx b/vtkm/filter/ContourInteger.cxx index 007b537c2..c7229350c 100644 --- a/vtkm/filter/ContourInteger.cxx +++ b/vtkm/filter/ContourInteger.cxx @@ -23,11 +23,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, @@ -35,11 +37,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif } } diff --git a/vtkm/filter/ContourScalar.cxx b/vtkm/filter/ContourScalar.cxx index aa0e58135..733e7b87a 100644 --- a/vtkm/filter/ContourScalar.cxx +++ b/vtkm/filter/ContourScalar.cxx @@ -23,11 +23,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, @@ -35,11 +37,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif } } diff --git a/vtkm/filter/Gradient.h b/vtkm/filter/Gradient.h index e6e842faf..4fb9fa34b 100644 --- a/vtkm/filter/Gradient.h +++ b/vtkm/filter/Gradient.h @@ -117,11 +117,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, @@ -129,11 +131,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, @@ -141,11 +145,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, @@ -153,11 +159,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, diff --git a/vtkm/filter/GradientScalar.cxx b/vtkm/filter/GradientScalar.cxx index 7e3438b78..a59d6ca77 100644 --- a/vtkm/filter/GradientScalar.cxx +++ b/vtkm/filter/GradientScalar.cxx @@ -23,11 +23,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, @@ -35,11 +37,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif } } diff --git a/vtkm/filter/GradientVector.cxx b/vtkm/filter/GradientVector.cxx index 548d7ce95..d2a8c2dcb 100644 --- a/vtkm/filter/GradientVector.cxx +++ b/vtkm/filter/GradientVector.cxx @@ -23,11 +23,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, @@ -35,11 +37,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +#endif } } diff --git a/vtkm/internal/CMakeLists.txt b/vtkm/internal/CMakeLists.txt index f5523506f..2019eb291 100755 --- a/vtkm/internal/CMakeLists.txt +++ b/vtkm/internal/CMakeLists.txt @@ -35,6 +35,8 @@ endif() set(VTKM_ENABLE_LOGGING ${VTKm_ENABLE_LOGGING}) +set(VTKM_NO_DEPRECATED_VIRTUAL ${VTKm_NO_DEPRECATED_VIRTUAL}) + vtkm_get_kit_name(kit_name kit_dir) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Configure.h.in ${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/Configure.h diff --git a/vtkm/internal/Configure.h.in b/vtkm/internal/Configure.h.in index 5c81229c0..dc37a7d7d 100644 --- a/vtkm/internal/Configure.h.in +++ b/vtkm/internal/Configure.h.in @@ -301,6 +301,9 @@ //Mark if we have enabled logging. #cmakedefine VTKM_ENABLE_LOGGING +#ifndef VTKM_NO_DEPRECATED_VIRTUAL +#cmakedefine VTKM_NO_DEPRECATED_VIRTUAL +#endif // Define a pair of macros, VTKM_SWALLOW_SEMICOLON_PRE_BLOCK and // VTKM_SWALLOW_SEMICOLON_POST_BLOCK that can be used around a block in a diff --git a/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx b/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx index 980e213ec..f47eb2a62 100644 --- a/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx +++ b/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx @@ -44,12 +44,14 @@ struct CheckSameCoordinateSystem CheckSameField{}(originalArray, fileCoords); } +#ifndef VTKM_NO_DEPRECATED_VIRTUAL template void operator()(const vtkm::cont::ArrayHandleVirtual& originalArray, const vtkm::cont::CoordinateSystem& fileCoords) const { CheckSameField{}(originalArray, fileCoords); } +#endif void operator()(const vtkm::cont::ArrayHandleUniformPointCoordinates& originalArray, const vtkm::cont::CoordinateSystem& fileCoords) const diff --git a/vtkm/worklet/Keys.h b/vtkm/worklet/Keys.h index ab9b7841a..de00c715f 100644 --- a/vtkm/worklet/Keys.h +++ b/vtkm/worklet/Keys.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -444,10 +443,6 @@ struct Transport::BuildArrays( \ const vtkm::cont::ArrayHandle& keys, \ vtkm::worklet::KeysSortType sort, \ - vtkm::cont::DeviceAdapterId device); \ - extern template VTKM_WORKLET_TEMPLATE_EXPORT VTKM_CONT void vtkm::worklet::Keys::BuildArrays( \ - const vtkm::cont::ArrayHandleVirtual& keys, \ - vtkm::worklet::KeysSortType sort, \ vtkm::cont::DeviceAdapterId device) VTK_M_KEYS_EXPORT(vtkm::UInt8); diff --git a/vtkm/worklet/KeysSignedTypes.cxx b/vtkm/worklet/KeysSignedTypes.cxx index d3cbc7f53..f3b170edc 100644 --- a/vtkm/worklet/KeysSignedTypes.cxx +++ b/vtkm/worklet/KeysSignedTypes.cxx @@ -17,10 +17,6 @@ template VTKM_WORKLET_EXPORT VTKM_CONT void vtkm::worklet::Keys::BuildArrays( \ const vtkm::cont::ArrayHandle& keys, \ vtkm::worklet::KeysSortType sort, \ - vtkm::cont::DeviceAdapterId device); \ - template VTKM_WORKLET_EXPORT VTKM_CONT void vtkm::worklet::Keys::BuildArrays( \ - const vtkm::cont::ArrayHandleVirtual& keys, \ - vtkm::worklet::KeysSortType sort, \ vtkm::cont::DeviceAdapterId device) VTK_M_KEYS_EXPORT(vtkm::Id); diff --git a/vtkm/worklet/KeysUnsignedTypes.cxx b/vtkm/worklet/KeysUnsignedTypes.cxx index a20755050..b68a8acae 100644 --- a/vtkm/worklet/KeysUnsignedTypes.cxx +++ b/vtkm/worklet/KeysUnsignedTypes.cxx @@ -17,10 +17,6 @@ template VTKM_WORKLET_EXPORT VTKM_CONT void vtkm::worklet::Keys::BuildArrays( \ const vtkm::cont::ArrayHandle& keys, \ vtkm::worklet::KeysSortType sort, \ - vtkm::cont::DeviceAdapterId device); \ - template VTKM_WORKLET_EXPORT VTKM_CONT void vtkm::worklet::Keys::BuildArrays( \ - const vtkm::cont::ArrayHandleVirtual& keys, \ - vtkm::worklet::KeysSortType sort, \ vtkm::cont::DeviceAdapterId device) VTK_M_KEYS_EXPORT(vtkm::HashType); diff --git a/vtkm/worklet/PointMerge.h b/vtkm/worklet/PointMerge.h index ce897a203..9b173b36a 100644 --- a/vtkm/worklet/PointMerge.h +++ b/vtkm/worklet/PointMerge.h @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -440,7 +439,7 @@ public: Run(delta, fastCheck, bounds, concretePoints); - // Make sure that the modified points are reflected back in the virtual array. + // Make sure that the modified points are reflected back in the variant array. points = concretePoints; } diff --git a/vtkm/worklet/testing/UnitTestOrientNormals.cxx b/vtkm/worklet/testing/UnitTestOrientNormals.cxx index dddd81de5..8a1e84939 100644 --- a/vtkm/worklet/testing/UnitTestOrientNormals.cxx +++ b/vtkm/worklet/testing/UnitTestOrientNormals.cxx @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include From cd08fd49955dc184e99cd9b20bec6897446eb0f4 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 3 Sep 2020 14:07:41 -0600 Subject: [PATCH 16/51] Add changelog for removing virtual methods The changelog is not quite accurate because it is claiming that all virtual methods are removed when that is not quite the case. Hopefully soon the changelog text will be accurate. --- docs/changelog/deprecate-virtual-methods.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs/changelog/deprecate-virtual-methods.md diff --git a/docs/changelog/deprecate-virtual-methods.md b/docs/changelog/deprecate-virtual-methods.md new file mode 100644 index 000000000..ff7d3ed36 --- /dev/null +++ b/docs/changelog/deprecate-virtual-methods.md @@ -0,0 +1,17 @@ +# Virtual methods in execution environment deprecated + +The use of classes with any virtual methods in the execution environment is +deprecated. Although we had code to correctly build virtual methods on some +devices such as CUDA, this feature was not universally supported on all +programming models we wish to support. Plus, the implementation of virtual +methods is not hugely convenient on CUDA because the virtual methods could +not be embedded in a library. To get around virtual methods declared in +different libraries, all builds had to be static, and a special linking +step to pull in possible virtual method implementations was required. + +For these reasons, VTK-m is no longer relying on virtual methods. (Other +approaches like multiplexers are used instead.) The code will be officially +removed in version 2.0. It is still supported in a deprecated sense (you +should get a warning). However, if you want to build without virtual +methods, you can set the `VTKm_NO_DEPRECATED_VIRTUAL` CMake flag, and they +will not be compiled. From 89cf93a66b3436051fb894d6ae9d6a3e5f74c1df Mon Sep 17 00:00:00 2001 From: nadavi Date: Wed, 26 Aug 2020 17:29:38 +0000 Subject: [PATCH 17/51] fix OpenMP PRAGMA warnings for auto-associated looping variable types --- vtkm/cont/openmp/internal/FunctorsOpenMP.h | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/vtkm/cont/openmp/internal/FunctorsOpenMP.h b/vtkm/cont/openmp/internal/FunctorsOpenMP.h index 9ada47cf2..472c0ea65 100644 --- a/vtkm/cont/openmp/internal/FunctorsOpenMP.h +++ b/vtkm/cont/openmp/internal/FunctorsOpenMP.h @@ -379,9 +379,9 @@ struct ReduceHelper // This gives faster code for floats and non-trivial types. template static ReturnType DoParallelReduction(IterType data, - vtkm::Id numVals, - int tid, - int numThreads, + const vtkm::Id& numVals, + const int& tid, + const int& numThreads, FunctorType f, std::false_type /* isIntegral */) { @@ -389,18 +389,24 @@ struct ReduceHelper ReturnType accum = f(data[2 * tid], data[2 * tid + 1]); const vtkm::Id offset = numThreads * 2; - const vtkm::Id end = std::max(vtkm::Id(((numVals / 4) * 4) - 4), offset); + const vtkm::Id end = std::max(((numVals / 4) * 4) - 4, offset); const vtkm::Id unrollEnd = end - ((end - offset) % 4); - vtkm::Id i = offset; + +// When initializing the looping iterator to a non integral type, intel compilers will +// convert the iterator type to an unsigned value +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" VTKM_OPENMP_DIRECTIVE(for schedule(static)) for (i = offset; i < unrollEnd; i += 4) +#pragma GCC diagnostic pop { const auto t1 = f(data[i], data[i + 1]); const auto t2 = f(data[i + 2], data[i + 3]); accum = f(accum, t1); accum = f(accum, t2); } + // Let the last thread mop up any remaining values as it would // have just accessed the adjacent data if (tid == numThreads - 1) @@ -418,18 +424,21 @@ struct ReduceHelper // hurt performance. template static ReturnType DoParallelReduction(IterType data, - vtkm::Id numVals, - int tid, - int numThreads, + const vtkm::Id& numVals, + const int& tid, + const int& numThreads, FunctorType f, std::true_type /* isIntegral */) { // Use the first (numThreads*2) values for initializing: ReturnType accum = f(data[2 * tid], data[2 * tid + 1]); - // Assign each thread chunks of the remaining values for local reduction +// Assign each thread chunks of the remaining values for local reduction +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" VTKM_OPENMP_DIRECTIVE(for schedule(static)) for (vtkm::Id i = numThreads * 2; i < numVals; i++) +#pragma GCC diagnostic pop { accum = f(accum, data[i]); } From 18263a37ac6b22fe222022d65a7ff99063e145eb Mon Sep 17 00:00:00 2001 From: nadavi Date: Wed, 26 Aug 2020 17:29:00 +0000 Subject: [PATCH 18/51] update float casting to not have warnings on iris --- vtkm/worklet/contour/FlyingEdgesPass4X.h | 13 ++++++++++--- vtkm/worklet/contour/FlyingEdgesPass4XWithNormals.h | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/vtkm/worklet/contour/FlyingEdgesPass4X.h b/vtkm/worklet/contour/FlyingEdgesPass4X.h index 8035f94bd..279e32fa7 100644 --- a/vtkm/worklet/contour/FlyingEdgesPass4X.h +++ b/vtkm/worklet/contour/FlyingEdgesPass4X.h @@ -308,11 +308,18 @@ struct ComputePass4X : public vtkm::worklet::WorkletVisitCellsWithPoints { return vtkm::Vec3f( this->Origin[0] + - this->Spacing[0] * static_cast(ijk0[0] + t * (ijk1[0] - ijk0[0])), + this->Spacing[0] * + (static_cast(ijk0[0]) + + static_cast(t) * static_cast(ijk1[0] - ijk0[0])), this->Origin[1] + - this->Spacing[1] * static_cast(ijk0[1] + t * (ijk1[1] - ijk0[1])), + this->Spacing[1] * + (static_cast(ijk0[1]) + + static_cast(t) * static_cast(ijk1[1] - ijk0[1])), this->Origin[2] + - this->Spacing[2] * static_cast(ijk0[2] + t * (ijk1[2] - ijk0[2]))); + this->Spacing[2] * + (static_cast(ijk0[2]) + + static_cast(t) * + static_cast(ijk1[2] - ijk0[2]))); } }; } diff --git a/vtkm/worklet/contour/FlyingEdgesPass4XWithNormals.h b/vtkm/worklet/contour/FlyingEdgesPass4XWithNormals.h index f4768c634..f5e728404 100644 --- a/vtkm/worklet/contour/FlyingEdgesPass4XWithNormals.h +++ b/vtkm/worklet/contour/FlyingEdgesPass4XWithNormals.h @@ -354,11 +354,18 @@ struct ComputePass4XWithNormals : public vtkm::worklet::WorkletVisitCellsWithPoi { return vtkm::Vec3f( this->Origin[0] + - this->Spacing[0] * static_cast(ijk0[0] + t * (ijk1[0] - ijk0[0])), + this->Spacing[0] * + (static_cast(ijk0[0]) + + static_cast(t) * static_cast(ijk1[0] - ijk0[0])), this->Origin[1] + - this->Spacing[1] * static_cast(ijk0[1] + t * (ijk1[1] - ijk0[1])), + this->Spacing[1] * + (static_cast(ijk0[1]) + + static_cast(t) * static_cast(ijk1[1] - ijk0[1])), this->Origin[2] + - this->Spacing[2] * static_cast(ijk0[2] + t * (ijk1[2] - ijk0[2]))); + this->Spacing[2] * + (static_cast(ijk0[2]) + + static_cast(t) * + static_cast(ijk1[2] - ijk0[2]))); } //---------------------------------------------------------------------------- From 843307bcf7669215dd401379f6f7e53126a18217 Mon Sep 17 00:00:00 2001 From: nadavi Date: Thu, 3 Sep 2020 22:27:27 +0000 Subject: [PATCH 19/51] fix floating point casting warning in worklet test --- vtkm/worklet/testing/UnitTestDescriptiveStatistics.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vtkm/worklet/testing/UnitTestDescriptiveStatistics.cxx b/vtkm/worklet/testing/UnitTestDescriptiveStatistics.cxx index f4abd6de7..1f6550215 100644 --- a/vtkm/worklet/testing/UnitTestDescriptiveStatistics.cxx +++ b/vtkm/worklet/testing/UnitTestDescriptiveStatistics.cxx @@ -192,7 +192,7 @@ void TestVarianceProperty() { condition_number_kv += vtkm::Abs(rp.Get(i) - mean_kv) * vtkm::Abs(rp.Get(i)); } - condition_number_kv *= (2.0f / ((rp.GetNumberOfValues() - 1) * var_kv)); + condition_number_kv *= (2.0f / (static_cast(rp.GetNumberOfValues() - 1) * var_kv)); VTKM_TEST_ASSERT(test_equal(var_kv, 4.0 * 4.0 * var_v, condition_number_kv * std::numeric_limits::epsilon())); @@ -210,7 +210,7 @@ void TestVarianceProperty() { condition_number_v += vtkm::Abs(rp.Get(i) - mean_v) * vtkm::Abs(rp.Get(i)); } - condition_number_v *= (2.0f / ((rp.GetNumberOfValues() - 1) * var_v)); + condition_number_v *= (2.0f / (static_cast(rp.GetNumberOfValues() - 1) * var_v)); VTKM_TEST_ASSERT( test_equal(var_v, var_px, condition_number_v * std::numeric_limits::epsilon())); From 284774cf43d087bf836ae65d3b2378a820c43cc7 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 3 Sep 2020 14:22:15 -0600 Subject: [PATCH 20/51] Turn on "no virtual" option on some CI builds Make sure that the `VTKm_NO_DEPRECATED_VIRTUAL` CMake option is building correctly by adding it to some of the CI builds. --- .gitlab/ci/config/initial_config.cmake | 3 +++ .gitlab/ci/ubuntu1604.yml | 2 +- .gitlab/ci/ubuntu1804.yml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitlab/ci/config/initial_config.cmake b/.gitlab/ci/config/initial_config.cmake index e4df50de0..c58a3935b 100644 --- a/.gitlab/ci/config/initial_config.cmake +++ b/.gitlab/ci/config/initial_config.cmake @@ -49,6 +49,9 @@ foreach(option IN LISTS options) elseif(no_rendering STREQUAL option) set(VTKm_ENABLE_RENDERING "OFF" CACHE STRING "") + elseif(no_virtual STREQUAL option) + set(VTKm_NO_DEPRECATED_VIRTUAL "ON" CACHE STRING "") + elseif(examples STREQUAL option) set(VTKm_ENABLE_EXAMPLES "ON" CACHE STRING "") diff --git a/.gitlab/ci/ubuntu1604.yml b/.gitlab/ci/ubuntu1604.yml index 948f3a139..ce4b43231 100644 --- a/.gitlab/ci/ubuntu1604.yml +++ b/.gitlab/ci/ubuntu1604.yml @@ -17,7 +17,7 @@ build:ubuntu1604_gcc5: CC: "gcc-5" CXX: "g++-5" CMAKE_BUILD_TYPE: RelWithDebInfo - VTKM_SETTINGS: "cuda+pascal" + VTKM_SETTINGS: "cuda+pascal+no_virtual" test:ubuntu1604_gcc5: tags: diff --git a/.gitlab/ci/ubuntu1804.yml b/.gitlab/ci/ubuntu1804.yml index a83c45796..41c4858f8 100644 --- a/.gitlab/ci/ubuntu1804.yml +++ b/.gitlab/ci/ubuntu1804.yml @@ -55,7 +55,7 @@ build:ubuntu1804_gcc7: variables: CC: "gcc-7" CXX: "g++-7" - VTKM_SETTINGS: "cuda+turing+mpi+64bit_floats" + VTKM_SETTINGS: "cuda+turing+mpi+64bit_floats+no_virtual" test:ubuntu1804_gcc7: tags: From b27e4c7ea6d632bcf1a9f94f8125ad2475f3b267 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 8 Sep 2020 07:52:50 -0600 Subject: [PATCH 21/51] Ignore files for deprecated virtual classes for SourceInInstall test If `VTKm_NO_DEPRECATED_VIRTUAL` is on, then these classes are not installed. Thus, add exceptions for these files to avoid test failures. We could get fancier by only checking if `VTKm_NO_DEPRECATED_VIRTUAL` is off, but that seems heavy-handed to make a regression test for something that will go away. These exceptions should be removed once the files are removed. --- CMake/testing/VTKmCheckSourceInInstall.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMake/testing/VTKmCheckSourceInInstall.cmake b/CMake/testing/VTKmCheckSourceInInstall.cmake index fd0d771ca..abf71d1f4 100644 --- a/CMake/testing/VTKmCheckSourceInInstall.cmake +++ b/CMake/testing/VTKmCheckSourceInInstall.cmake @@ -112,6 +112,14 @@ function(do_verify root_dir prefix) set(file_exceptions cont/ColorTablePrivate.hxx thirdparty/diy/vtkmdiy/cmake/mpi_types.h + + # Ignore deprecated virtual classes (which are not installed if VTKm_NO_DEPRECATED_VIRTUAL + # is on). These exceptions can be removed when these files are completely removed. + cont/ArrayHandleVirtual.h + cont/ArrayHandleVirtual.hxx + cont/ArrayHandleVirtualCoordinates.h + cont/StorageVirtual.h + cont/StorageVirtual.hxx ) #by default every header in a testing directory doesn't need to be installed From f7cc03107d06a2c3ca3c5db6056fcd5e314e6b19 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Tue, 8 Sep 2020 08:30:02 -0600 Subject: [PATCH 22/51] Fix deprecated warnings Supress the deprecated class warnings for the implementation of deprecated features. --- benchmarking/BenchmarkFieldAlgorithms.cxx | 8 ++++++++ vtkm/cont/ArrayHandleVirtual.cxx | 5 +++++ vtkm/cont/ArrayHandleVirtualCoordinates.h | 6 ++---- vtkm/cont/ArrayRangeCompute.hxx | 2 ++ vtkm/cont/testing/UnitTestVariantArrayHandle.cxx | 2 ++ vtkm/filter/Contour.h | 8 ++++++++ vtkm/filter/ContourInteger.cxx | 4 ++++ vtkm/filter/ContourScalar.cxx | 4 ++++ vtkm/filter/Gradient.h | 10 +++++++++- vtkm/filter/GradientScalar.cxx | 4 ++++ vtkm/filter/GradientVector.cxx | 4 ++++ vtkm/io/testing/UnitTestVTKDataSetWriter.cxx | 2 ++ 12 files changed, 54 insertions(+), 5 deletions(-) diff --git a/benchmarking/BenchmarkFieldAlgorithms.cxx b/benchmarking/BenchmarkFieldAlgorithms.cxx index 0228ecff4..a23c2c3b8 100644 --- a/benchmarking/BenchmarkFieldAlgorithms.cxx +++ b/benchmarking/BenchmarkFieldAlgorithms.cxx @@ -440,10 +440,12 @@ VTKM_BENCHMARK_TEMPLATES(BenchBlackScholesStatic, ValueTypes); template void BenchBlackScholesDynamic(::benchmark::State& state) { + VTKM_DEPRECATED_SUPPRESS_BEGIN BenchBlackScholesImpl impl{ state }; impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.StockPrice), vtkm::cont::make_ArrayHandleVirtual(impl.OptionStrike), vtkm::cont::make_ArrayHandleVirtual(impl.OptionYears)); + VTKM_DEPRECATED_SUPPRESS_END }; VTKM_BENCHMARK_TEMPLATES(BenchBlackScholesDynamic, ValueTypes); #endif //VTKM_NO_DEPRECATED_VIRTUAL @@ -546,10 +548,12 @@ VTKM_BENCHMARK_TEMPLATES(BenchMathStatic, ValueTypes); template void BenchMathDynamic(::benchmark::State& state) { + VTKM_DEPRECATED_SUPPRESS_BEGIN BenchMathImpl impl{ state }; impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.InputHandle), vtkm::cont::make_ArrayHandleVirtual(impl.TempHandle1), vtkm::cont::make_ArrayHandleVirtual(impl.TempHandle2)); + VTKM_DEPRECATED_SUPPRESS_END }; VTKM_BENCHMARK_TEMPLATES(BenchMathDynamic, ValueTypes); #endif //VTKM_NO_DEPRECATED_VIRTUAL @@ -647,8 +651,10 @@ VTKM_BENCHMARK_TEMPLATES(BenchFusedMathStatic, ValueTypes); template void BenchFusedMathDynamic(::benchmark::State& state) { + VTKM_DEPRECATED_SUPPRESS_BEGIN BenchFusedMathImpl impl{ state }; impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.InputHandle)); + VTKM_DEPRECATED_SUPPRESS_END }; VTKM_BENCHMARK_TEMPLATES(BenchFusedMathDynamic, ValueTypes); #endif //VTKM_NO_DEPRECATED_VIRTUAL @@ -769,10 +775,12 @@ VTKM_BENCHMARK_TEMPLATES(BenchEdgeInterpStatic, InterpValueTypes); template void BenchEdgeInterpDynamic(::benchmark::State& state) { + VTKM_DEPRECATED_SUPPRESS_BEGIN BenchEdgeInterpImpl impl{ state }; impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.EdgePairHandle), vtkm::cont::make_ArrayHandleVirtual(impl.WeightHandle), vtkm::cont::make_ArrayHandleVirtual(impl.FieldHandle)); + VTKM_DEPRECATED_SUPPRESS_END }; VTKM_BENCHMARK_TEMPLATES(BenchEdgeInterpDynamic, InterpValueTypes); #endif //VTKM_NO_DEPRECATED_VIRTUAL diff --git a/vtkm/cont/ArrayHandleVirtual.cxx b/vtkm/cont/ArrayHandleVirtual.cxx index f6561de5b..062573a68 100644 --- a/vtkm/cont/ArrayHandleVirtual.cxx +++ b/vtkm/cont/ArrayHandleVirtual.cxx @@ -15,6 +15,8 @@ namespace vtkm namespace cont { +VTKM_DEPRECATED_SUPPRESS_BEGIN + #define VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(T) \ template class VTKM_CONT_EXPORT ArrayHandle; \ template class VTKM_CONT_EXPORT ArrayHandleVirtual; \ @@ -38,5 +40,8 @@ VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float32); VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float64); #undef VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE + +VTKM_DEPRECATED_SUPPRESS_END + } } //namespace vtkm::cont diff --git a/vtkm/cont/ArrayHandleVirtualCoordinates.h b/vtkm/cont/ArrayHandleVirtualCoordinates.h index 64cf7454c..bebb5b7f2 100644 --- a/vtkm/cont/ArrayHandleVirtualCoordinates.h +++ b/vtkm/cont/ArrayHandleVirtualCoordinates.h @@ -31,6 +31,8 @@ namespace vtkm namespace cont { +VTKM_DEPRECATED_SUPPRESS_BEGIN + /// ArrayHandleVirtualCoordinates is a specialization of ArrayHandle. class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Virtual ArrayHandles are being phased out.") ArrayHandleVirtualCoordinates final : public vtkm::cont::ArrayHandleVirtual @@ -39,17 +41,13 @@ public: VTKM_ARRAY_HANDLE_SUBCLASS_NT(ArrayHandleVirtualCoordinates, (vtkm::cont::ArrayHandleVirtual)); - VTKM_DEPRECATED_SUPPRESS_BEGIN template explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle& ah) : vtkm::cont::ArrayHandleVirtual(vtkm::cont::make_ArrayHandleCast(ah)) { } - VTKM_DEPRECATED_SUPPRESS_END }; -VTKM_DEPRECATED_SUPPRESS_BEGIN - template void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords, Functor&& f, diff --git a/vtkm/cont/ArrayRangeCompute.hxx b/vtkm/cont/ArrayRangeCompute.hxx index 4b59f206e..33a41ee0a 100644 --- a/vtkm/cont/ArrayRangeCompute.hxx +++ b/vtkm/cont/ArrayRangeCompute.hxx @@ -95,6 +95,7 @@ inline vtkm::cont::ArrayHandle ArrayRangeComputeImpl( #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN VTKM_CONT inline vtkm::cont::ArrayHandle ArrayRangeCompute( const vtkm::cont::ArrayHandleVirtual& input, @@ -133,6 +134,7 @@ inline vtkm::cont::ArrayHandle ArrayRangeCompute( return detail::ArrayRangeComputeImpl(input, device); } } +VTKM_DEPRECATED_SUPPRESS_END #endif //VTKM_NO_DEPRECATED_VIRTUAL template diff --git a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx index f954f59e6..8091c5438 100644 --- a/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestVariantArrayHandle.cxx @@ -118,6 +118,7 @@ struct CheckFunctor } #ifndef VTKM_NO_DEPRECATED_VIRTUAL + VTKM_DEPRECATED_SUPPRESS_BEGIN template void operator()(const vtkm::cont::ArrayHandleVirtual& array, bool& vtkmNotUsed(calledBasic), @@ -128,6 +129,7 @@ struct CheckFunctor CheckArray(array); } + VTKM_DEPRECATED_SUPPRESS_END #endif //VTKM_NO_DEPRECATED_VIRTUAL template diff --git a/vtkm/filter/Contour.h b/vtkm/filter/Contour.h index 6bf23a061..aa1a237ca 100644 --- a/vtkm/filter/Contour.h +++ b/vtkm/filter/Contour.h @@ -182,11 +182,13 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( @@ -196,11 +198,13 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( @@ -210,11 +214,13 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( @@ -224,11 +230,13 @@ extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour: vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_CONTOUR_TEMPLATE_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif #endif //!vtkm_filter_ContourExecute_cxx diff --git a/vtkm/filter/ContourInteger.cxx b/vtkm/filter/ContourInteger.cxx index c7229350c..8dd3219fb 100644 --- a/vtkm/filter/ContourInteger.cxx +++ b/vtkm/filter/ContourInteger.cxx @@ -24,11 +24,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( @@ -38,11 +40,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif } } diff --git a/vtkm/filter/ContourScalar.cxx b/vtkm/filter/ContourScalar.cxx index 733e7b87a..ca87b6a83 100644 --- a/vtkm/filter/ContourScalar.cxx +++ b/vtkm/filter/ContourScalar.cxx @@ -24,11 +24,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( @@ -38,11 +40,13 @@ template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_CONTOUR_EXPORT vtkm::cont::DataSet Contour::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif } } diff --git a/vtkm/filter/Gradient.h b/vtkm/filter/Gradient.h index 4fb9fa34b..800b2a9cd 100644 --- a/vtkm/filter/Gradient.h +++ b/vtkm/filter/Gradient.h @@ -118,11 +118,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( @@ -132,11 +134,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( @@ -146,11 +150,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( @@ -160,11 +166,13 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradient::DoExecute( @@ -173,7 +181,7 @@ extern template VTKM_FILTER_GRADIENT_TEMPLATE_EXPORT vtkm::cont::DataSet Gradien const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); -#endif +#endif //vtkm_filter_Gradient_cxx } } // namespace vtkm::filter diff --git a/vtkm/filter/GradientScalar.cxx b/vtkm/filter/GradientScalar.cxx index a59d6ca77..891391a60 100644 --- a/vtkm/filter/GradientScalar.cxx +++ b/vtkm/filter/GradientScalar.cxx @@ -24,11 +24,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( @@ -38,11 +40,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif } } diff --git a/vtkm/filter/GradientVector.cxx b/vtkm/filter/GradientVector.cxx index d2a8c2dcb..af7b63cdf 100644 --- a/vtkm/filter/GradientVector.cxx +++ b/vtkm/filter/GradientVector.cxx @@ -24,11 +24,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( @@ -38,11 +40,13 @@ template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( vtkm::filter::PolicyBase); #ifndef VTKM_NO_DEPRECATED_VIRTUAL +VTKM_DEPRECATED_SUPPRESS_BEGIN template VTKM_FILTER_GRADIENT_EXPORT vtkm::cont::DataSet Gradient::DoExecute( const vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase); +VTKM_DEPRECATED_SUPPRESS_END #endif } } diff --git a/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx b/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx index f47eb2a62..a2604eb47 100644 --- a/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx +++ b/vtkm/io/testing/UnitTestVTKDataSetWriter.cxx @@ -45,12 +45,14 @@ struct CheckSameCoordinateSystem } #ifndef VTKM_NO_DEPRECATED_VIRTUAL + VTKM_DEPRECATED_SUPPRESS_BEGIN template void operator()(const vtkm::cont::ArrayHandleVirtual& originalArray, const vtkm::cont::CoordinateSystem& fileCoords) const { CheckSameField{}(originalArray, fileCoords); } + VTKM_DEPRECATED_SUPPRESS_END #endif void operator()(const vtkm::cont::ArrayHandleUniformPointCoordinates& originalArray, From e706880d7bf295da5606c63da3a940922876cd97 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 9 Sep 2020 06:09:39 -0600 Subject: [PATCH 23/51] Fix unnecessary deprecation warnings in visual studio When using a deprecated `ArrayHandle`, you should get the warning when you declare it, not when it's used in a templated class or method. --- vtkm/cont/arg/TransportTagArrayIn.h | 13 +++++++++++++ vtkm/cont/arg/TransportTagArrayInOut.h | 13 +++++++++++++ vtkm/cont/arg/TransportTagArrayOut.h | 13 +++++++++++++ vtkm/cont/arg/TransportTagWholeArrayIn.h | 13 +++++++++++++ vtkm/cont/arg/TransportTagWholeArrayInOut.h | 13 +++++++++++++ vtkm/cont/arg/TransportTagWholeArrayOut.h | 13 +++++++++++++ 6 files changed, 78 insertions(+) diff --git a/vtkm/cont/arg/TransportTagArrayIn.h b/vtkm/cont/arg/TransportTagArrayIn.h index b346cfae2..f3d6e3c40 100644 --- a/vtkm/cont/arg/TransportTagArrayIn.h +++ b/vtkm/cont/arg/TransportTagArrayIn.h @@ -35,6 +35,15 @@ struct TransportTagArrayIn template struct Transport { + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif + VTKM_IS_ARRAY_HANDLE(ContObjectType); using ExecObjectType = decltype( @@ -54,6 +63,10 @@ struct Transport return object.PrepareForInput(Device(), token); } + +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_END +#endif }; } } diff --git a/vtkm/cont/arg/TransportTagArrayInOut.h b/vtkm/cont/arg/TransportTagArrayInOut.h index b70d905f2..86c53a61b 100644 --- a/vtkm/cont/arg/TransportTagArrayInOut.h +++ b/vtkm/cont/arg/TransportTagArrayInOut.h @@ -36,6 +36,15 @@ struct TransportTagArrayInOut template struct Transport { + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif + // If you get a compile error here, it means you tried to use an object that // is not an array handle as an argument that is expected to be one. VTKM_IS_ARRAY_HANDLE(ContObjectType); @@ -57,6 +66,10 @@ struct Transport struct Transport { + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif + // If you get a compile error here, it means you tried to use an object that // is not an array handle as an argument that is expected to be one. VTKM_IS_ARRAY_HANDLE(ContObjectType); @@ -53,6 +62,10 @@ struct Transport { return object.PrepareForOutput(outputRange, Device(), token); } + +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_END +#endif }; } } diff --git a/vtkm/cont/arg/TransportTagWholeArrayIn.h b/vtkm/cont/arg/TransportTagWholeArrayIn.h index bc15725aa..c4dad8e93 100644 --- a/vtkm/cont/arg/TransportTagWholeArrayIn.h +++ b/vtkm/cont/arg/TransportTagWholeArrayIn.h @@ -40,6 +40,15 @@ struct TransportTagWholeArrayIn template struct Transport { + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif + // If you get a compile error here, it means you tried to use an object that // is not an array handle as an argument that is expected to be one. VTKM_IS_ARRAY_HANDLE(ContObjectType); @@ -62,6 +71,10 @@ struct Transport struct Transport { + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif + // If you get a compile error here, it means you tried to use an object that // is not an array handle as an argument that is expected to be one. VTKM_IS_ARRAY_HANDLE(ContObjectType); @@ -64,6 +73,10 @@ struct Transport struct Transport { + // MSVC will issue deprecation warnings here if this template is instantiated with + // a deprecated class even if the template is used from a section of code where + // deprecation warnings are suppressed. This is annoying behavior since this template + // has no control over what class it is used with. To get around it, we have to + // suppress all deprecation warnings here. +#ifdef VTKM_MSVC + VTKM_DEPRECATED_SUPPRESS_BEGIN +#endif + // If you get a compile error here, it means you tried to use an object that // is not an array handle as an argument that is expected to be one. VTKM_IS_ARRAY_HANDLE(ContObjectType); @@ -64,6 +73,10 @@ struct Transport Date: Thu, 27 Aug 2020 17:09:55 -0600 Subject: [PATCH 24/51] Enable automatic transformation of Unknown/UncertainArrayHandle --- vtkm/cont/UncertainArrayHandle.h | 14 +++++++++++- vtkm/cont/UnknownArrayHandle.h | 12 ++++++++++ .../testing/UnitTestWorkletMapField.cxx | 22 ++++++++++--------- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/vtkm/cont/UncertainArrayHandle.h b/vtkm/cont/UncertainArrayHandle.h index 05739b4ca..f2da66b5c 100644 --- a/vtkm/cont/UncertainArrayHandle.h +++ b/vtkm/cont/UncertainArrayHandle.h @@ -116,8 +116,20 @@ VTKM_CONT vtkm::cont::UncertainArrayHandle { return vtkm::cont::UncertainArrayHandle(*this); } + +namespace internal +{ + +template +struct DynamicTransformTraits> +{ + using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; +}; + +} // namespace internal + } -} +} // namespace vtkm::cont //============================================================================= // Specializations of serialization related classes diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index 9a3d0119f..23066b49c 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -604,6 +604,18 @@ void CastAndCall(const UnknownArrayHandle& handle, Functor&& f, Args&&... args) handle.CastAndCallForTypes( std::forward(f), std::forward(args)...); } + +namespace internal +{ + +template <> +struct DynamicTransformTraits +{ + using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; +}; + +} // namespace internal + } } // namespace vtkm::cont diff --git a/vtkm/worklet/testing/UnitTestWorkletMapField.cxx b/vtkm/worklet/testing/UnitTestWorkletMapField.cxx index 9f07cd5f3..d50c58bc2 100644 --- a/vtkm/worklet/testing/UnitTestWorkletMapField.cxx +++ b/vtkm/worklet/testing/UnitTestWorkletMapField.cxx @@ -10,7 +10,8 @@ #include #include -#include +#include +#include #include #include @@ -122,25 +123,26 @@ struct DoVariantTestWorklet vtkm::cont::ArrayHandle inoutHandle; - std::cout << "Create and run dispatcher with variant arrays." << std::endl; + std::cout << "Create and run dispatcher with unknown arrays." << std::endl; vtkm::worklet::DispatcherMapField dispatcher; - vtkm::cont::VariantArrayHandle inputVariant(inputHandle); + vtkm::cont::UnknownArrayHandle inputVariant(inputHandle); { //Verify we can pass by value vtkm::cont::ArrayCopy(inputHandle, inoutHandle); - vtkm::cont::VariantArrayHandle outputVariant(outputHandle); - vtkm::cont::VariantArrayHandle inoutVariant(inoutHandle); - dispatcher.Invoke(inputVariant.ResetTypes(vtkm::List{}), - outputVariant.ResetTypes(vtkm::List{}), - inoutVariant.ResetTypes(vtkm::List{})); + vtkm::cont::UnknownArrayHandle outputVariant(outputHandle); + vtkm::cont::UnknownArrayHandle inoutVariant(inoutHandle); + dispatcher.Invoke( + inputVariant.ResetTypes, vtkm::List>(), + outputVariant.ResetTypes, vtkm::List>(), + inoutVariant.ResetTypes, vtkm::List>()); CheckPortal(outputHandle.ReadPortal()); CheckPortal(inoutHandle.ReadPortal()); } { //Verify we can pass by pointer - vtkm::cont::VariantArrayHandle outputVariant(outputHandle); - vtkm::cont::VariantArrayHandle inoutVariant(inoutHandle); + vtkm::cont::UnknownArrayHandle outputVariant(outputHandle); + vtkm::cont::UnknownArrayHandle inoutVariant(inoutHandle); vtkm::cont::ArrayCopy(inputHandle, inoutHandle); dispatcher.Invoke(&inputVariant, outputHandle, inoutHandle); From 1037aa756ec5eb0ed50479f3d6e46a1107a11bc3 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 10 Sep 2020 10:03:18 -0400 Subject: [PATCH 25/51] AssignerPartitionedDataSet: mark dtor as override --- vtkm/cont/AssignerPartitionedDataSet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/cont/AssignerPartitionedDataSet.h b/vtkm/cont/AssignerPartitionedDataSet.h index 095510e64..39c7f598d 100644 --- a/vtkm/cont/AssignerPartitionedDataSet.h +++ b/vtkm/cont/AssignerPartitionedDataSet.h @@ -59,7 +59,7 @@ public: AssignerPartitionedDataSet(vtkm::Id num_partitions); VTKM_CONT - virtual ~AssignerPartitionedDataSet(); + ~AssignerPartitionedDataSet() override; ///@{ /// vtkmdiy::Assigner API implementation. From 9b62c9eef176e7ca55471845e3fc4d1fa43a5208 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 08:39:27 -0600 Subject: [PATCH 26/51] Enable storing variable-sized Vecs in UnknownArrayHandle One of the features of `UnknownArrayHandle` is that it allows you to query how many `Vec` components each value has without resolve the type of the array. The functionality to implement this failed if you tried to store an `ArrayHandle` that stored `Vec`-like objects with `Vec` sizes that varied from value to value (i.e. an `ArrayHandleGroupVecVariable`). Storing such an array in `UnknownArrayHandle` might not be the best idea, but it should probably work. This change allows you to store such an array. If you try to query the number of components, you will get 0. --- vtkm/cont/UnknownArrayHandle.h | 17 ++++++++++++- .../testing/UnitTestUnknownArrayHandle.cxx | 25 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index 23066b49c..3ec73838b 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -51,10 +51,23 @@ static vtkm::Id UnknownAHNumberOfValues(void* mem) return arrayHandle->GetNumberOfValues(); } +template ::IsSizeStatic> +struct UnknownAHNumberOfComponentsImpl; +template +struct UnknownAHNumberOfComponentsImpl +{ + static constexpr vtkm::IdComponent Value = vtkm::VecTraits::NUM_COMPONENTS; +}; +template +struct UnknownAHNumberOfComponentsImpl +{ + static constexpr vtkm::IdComponent Value = 0; +}; + template static vtkm::IdComponent UnknownAHNumberOfComponents() { - return vtkm::VecTraits::NUM_COMPONENTS; + return UnknownAHNumberOfComponentsImpl::Value; } template @@ -303,6 +316,8 @@ public: /// /// If the array holds `vtkm::Vec` objects, this will return the number of components /// in each value. If the array holds a basic C type (such as `float`), this will return 1. + /// If the array holds `Vec`-like objects that have the number of components that can vary + /// at runtime, this method will return 0 (because there is no consistent answer). /// VTKM_CONT vtkm::IdComponent GetNumberOfComponents() const { diff --git a/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx index ceef14aee..b9424b24f 100644 --- a/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx +++ b/vtkm/cont/testing/UnitTestUnknownArrayHandle.cxx @@ -11,6 +11,12 @@ #include #include +#include +#include +#include +#include +#include + #include #include @@ -237,6 +243,25 @@ void CheckAsArrayHandle(const ArrayHandleType& array) ArrayHandleType retrievedArray = arrayUnknown2.AsArrayHandle(); VTKM_TEST_ASSERT(array == retrievedArray); } + + { + std::cout << " Try adding arrays with variable amounts of components" << std::endl; + // There might be some limited functionality, but you should still be able + // to get arrays in and out. + + // Note, this is a bad way to implement this array. You should something like + // ArrayHandleGroupVec instead. + using VariableVecArrayType = + vtkm::cont::ArrayHandleGroupVecVariable>; + VariableVecArrayType inArray = vtkm::cont::make_ArrayHandleGroupVecVariable( + array, vtkm::cont::make_ArrayHandleCounting(0, 2, ARRAY_SIZE / 2 + 1)); + VTKM_TEST_ASSERT(inArray.GetNumberOfValues() == ARRAY_SIZE / 2); + vtkm::cont::UnknownArrayHandle arrayUnknown2 = inArray; + VTKM_TEST_ASSERT(arrayUnknown2.IsType()); + VariableVecArrayType retrievedArray = arrayUnknown2.AsArrayHandle(); + VTKM_TEST_ASSERT(retrievedArray == inArray); + } } // A vtkm::Vec if NumComps > 1, otherwise a scalar From 482266b4428bda47ec8b432056c0684cb6b1b1c2 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 10 Sep 2020 10:03:31 -0400 Subject: [PATCH 27/51] Particle: explicitly make the copy ctor and assignment op They are disabled because we have a custom destructor. --- vtkm/Particle.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/vtkm/Particle.h b/vtkm/Particle.h index 5107c79a9..3487c5cf0 100644 --- a/vtkm/Particle.h +++ b/vtkm/Particle.h @@ -129,6 +129,13 @@ public: VTKM_EXEC_CONT Particle() {} + VTKM_EXEC_CONT Particle(const vtkm::Particle& rhs) + : ParticleBase(rhs) + { + // This must not be defaulted, since defaulted copy constructors are + // troublesome with CUDA __host__ __device__ markup. + } + VTKM_EXEC_CONT ~Particle() noexcept override { // This must not be defaulted, since defaulted virtual destructors are @@ -146,6 +153,19 @@ public: { } + VTKM_EXEC_CONT Particle& operator=(const vtkm::Particle& rhs) + { + // This must not be defaulted, since defaulted assignment operators are + // troublesome with CUDA __host__ __device__ markup. + + if (&rhs == this) + { + return *this; + } + vtkm::ParticleBase::operator=(rhs); + return *this; + } + VTKM_EXEC_CONT vtkm::Vec3f Next(const vtkm::VecVariable& vectors, const vtkm::FloatDefault& length) override From 11996f133fd96c76568574e950112472688418b9 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 13:26:16 -0600 Subject: [PATCH 28/51] Remove virtual methods from ColorTable Virtual methods are being deprecated, so remove their use from the ColorTable classes. Instead of using a virtual method to look up a value in the ColorTable, we essentially use a switch statement. This change also simplified the code quite a bit. The execution object used to use pointers to handle the virtual objects. That is no longer necessary, so a simple `vtkm::exec::ColorTable` is returned for execution objects. (Note that this `ColorTable` contains pointers that are specific for the particular device.) This is a non- backward compabible change. However, the only place (outside of the `ColorTable` implementation itself) was a single worklet for converting scalars to colors (`vtkm::worklet::colorconversion::TransferFunction`). This is unlikely to affect anyone. I also "fixed" some names in enum structs. There has been some inconsistencies in VTK-m on whether items in an enum struct are capitolized or camel case. We seem to moving toward camel case, so deprecate some old names. --- CMake/testing/VTKmCheckSourceInInstall.cmake | 1 - vtkm/cont/ColorTable.cxx | 908 +++++++++++------- vtkm/cont/ColorTable.h | 308 +++--- vtkm/cont/ColorTable.hxx | 117 --- vtkm/cont/ColorTablePresets.cxx | 151 ++- vtkm/cont/ColorTablePrivate.hxx | 295 ------ vtkm/cont/testing/TestingColorTable.h | 76 +- vtkm/exec/ColorTable.h | 116 ++- vtkm/exec/ColorTable.hxx | 234 ++--- vtkm/filter/testing/UnitTestFieldToColors.cxx | 2 +- vtkm/rendering/Actor.cxx | 2 +- vtkm/rendering/ColorBarAnnotation.cxx | 2 +- .../colorconversion/TransferFunction.h | 16 +- 13 files changed, 1087 insertions(+), 1141 deletions(-) delete mode 100644 vtkm/cont/ColorTablePrivate.hxx diff --git a/CMake/testing/VTKmCheckSourceInInstall.cmake b/CMake/testing/VTKmCheckSourceInInstall.cmake index abf71d1f4..ccf303bd2 100644 --- a/CMake/testing/VTKmCheckSourceInInstall.cmake +++ b/CMake/testing/VTKmCheckSourceInInstall.cmake @@ -110,7 +110,6 @@ function(do_verify root_dir prefix) ) set(file_exceptions - cont/ColorTablePrivate.hxx thirdparty/diy/vtkmdiy/cmake/mpi_types.h # Ignore deprecated virtual classes (which are not installed if VTKm_NO_DEPRECATED_VIRTUAL diff --git a/vtkm/cont/ColorTable.cxx b/vtkm/cont/ColorTable.cxx index b5cef2700..f7af39f2b 100644 --- a/vtkm/cont/ColorTable.cxx +++ b/vtkm/cont/ColorTable.cxx @@ -13,16 +13,282 @@ #include #include -#include #include #include +namespace +{ + +template +struct MinDelta +{ +}; +// This value seems to work well for float ranges we have tested +template <> +struct MinDelta +{ + static constexpr int value = 2048; +}; +template <> +struct MinDelta +{ + static constexpr vtkm::Int64 value = 2048L; +}; + +// Reperesents the following: +// T m = std::numeric_limits::min(); +// EquivSizeIntT im; +// std::memcpy(&im, &m, sizeof(T)); +// +template +struct MinRepresentable +{ +}; +template <> +struct MinRepresentable +{ + static constexpr int value = 8388608; +}; +template <> +struct MinRepresentable +{ + static constexpr vtkm::Int64 value = 4503599627370496L; +}; + +inline bool rangeAlmostEqual(const vtkm::Range& r) +{ + vtkm::Int64 irange[2]; + // needs to be a memcpy to avoid strict aliasing issues, doing a count + // of 2*sizeof(T) to couple both values at the same time + std::memcpy(irange, &r.Min, sizeof(vtkm::Int64)); + std::memcpy(irange + 1, &r.Max, sizeof(vtkm::Int64)); + // determine the absolute delta between these two numbers. + const vtkm::Int64 delta = std::abs(irange[1] - irange[0]); + // If the numbers are not nearly equal, we don't touch them. This avoids running into + // pitfalls like BUG PV #17152. + return (delta < 1024) ? true : false; +} + +template +inline double expandRange(T r[2]) +{ + constexpr bool is_float32_type = std::is_same::value; + using IRange = typename std::conditional::type; + IRange irange[2]; + // needs to be a memcpy to avoid strict aliasing issues, doing a count + // of 2*sizeof(T) to couple both values at the same time + std::memcpy(irange, r, sizeof(T) * 2); + + const bool denormal = !std::isnormal(r[0]); + const IRange minInt = MinRepresentable::value; + const IRange minDelta = denormal ? minInt + MinDelta::value : MinDelta::value; + + // determine the absolute delta between these two numbers. + const vtkm::Int64 delta = std::abs(irange[1] - irange[0]); + + // if our delta is smaller than the min delta push out the max value + // so that it is equal to minRange + minDelta. When our range is entirely + // negative we should instead subtract from our max, to max a larger negative + // value + if (delta < minDelta) + { + if (irange[0] < 0) + { + irange[1] = irange[0] - minDelta; + } + else + { + irange[1] = irange[0] + minDelta; + } + + T result; + std::memcpy(&result, irange + 1, sizeof(T)); + return static_cast(result); + } + return static_cast(r[1]); +} + +inline vtkm::Range adjustRange(const vtkm::Range& r) +{ + const bool spans_zero_boundary = r.Min < 0 && r.Max > 0; + if (spans_zero_boundary) + { // nothing needs to be done, but this check is required. + // if we convert into integer space the delta difference will overflow + // an integer + return r; + } + if (rangeAlmostEqual(r)) + { + return r; + } + + // range should be left untouched as much as possible to + // to avoid loss of precision whenever possible. That is why + // we only modify the Max value + vtkm::Range result = r; + if (r.Min > static_cast(std::numeric_limits::lowest()) && + r.Max < static_cast(std::numeric_limits::max())) + { //We've found it best to offset it in float space if the numbers + //lay inside that representable range + float frange[2] = { static_cast(r.Min), static_cast(r.Max) }; + result.Max = expandRange(frange); + } + else + { + double drange[2] = { r.Min, r.Max }; + result.Max = expandRange(drange); + } + return result; +} + + +inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) +{ + vtkm::Vec rgb; + constexpr float onethird = 1.0f / 3.0f; + constexpr float onesixth = 1.0f / 6.0f; + constexpr float twothird = 2.0f / 3.0f; + constexpr float fivesixth = 5.0f / 6.0f; + + // compute RGB from HSV + if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red + { + rgb[1] = 1.0f; + rgb[0] = (onethird - hsv[0]) * 6.0f; + rgb[2] = 0.0f; + } + else if (hsv[0] > onethird && hsv[0] <= 0.5f) // green/blue + { + rgb[1] = 1.0f; + rgb[2] = (hsv[0] - onethird) * 6.0f; + rgb[0] = 0.0f; + } + else if (hsv[0] > 0.5 && hsv[0] <= twothird) // blue/green + { + rgb[2] = 1.0f; + rgb[1] = (twothird - hsv[0]) * 6.0f; + rgb[0] = 0.0f; + } + else if (hsv[0] > twothird && hsv[0] <= fivesixth) // blue/red + { + rgb[2] = 1.0f; + rgb[0] = (hsv[0] - twothird) * 6.0f; + rgb[1] = 0.0f; + } + else if (hsv[0] > fivesixth && hsv[0] <= 1.0) // red/blue + { + rgb[0] = 1.0f; + rgb[2] = (1.0f - hsv[0]) * 6.0f; + rgb[1] = 0.0f; + } + else // red/green + { + rgb[0] = 1.0f; + rgb[1] = hsv[0] * 6; + rgb[2] = 0.0f; + } + + // add Saturation to the equation. + rgb[0] = (hsv[1] * rgb[0] + (1.0f - hsv[1])); + rgb[1] = (hsv[1] * rgb[1] + (1.0f - hsv[1])); + rgb[2] = (hsv[1] * rgb[2] + (1.0f - hsv[1])); + + rgb[0] *= hsv[2]; + rgb[1] *= hsv[2]; + rgb[2] *= hsv[2]; + return rgb; +} + +// clang-format off +inline bool outside_vrange(double x) { return x < 0.0 || x > 1.0; } +inline bool outside_vrange(const vtkm::Vec& x) + { return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0; } +inline bool outside_vrange(const vtkm::Vec& x) + { return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0 || x[2] < 0.0 || x[2] > 1.0; } +inline bool outside_vrange(float x) { return x < 0.0f || x > 1.0f; } +inline bool outside_vrange(const vtkm::Vec& x) + { return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f; } +inline bool outside_vrange(const vtkm::Vec& x) + { return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f || x[2] < 0.0f || x[2] > 1.0f; } + +inline bool outside_range() { return false; } + +template +inline bool outside_range(T&& t) { return outside_vrange(t); } + +template +inline bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); } + +template +inline bool outside_range(T&& t, U&& u, V&& v, Args&&... args) +{ + return outside_vrange(t) || outside_vrange(u) || outside_vrange(v) || + outside_range(std::forward(args)...); +} +// clang-format on +} + namespace vtkm { namespace cont { +namespace detail +{ + +struct ColorTableInternals +{ + std::string Name; + + vtkm::ColorSpace Space = vtkm::ColorSpace::Lab; + vtkm::Range TableRange = { 1.0, 0.0 }; + + vtkm::Vec3f_32 NaNColor = { 0.5f, 0.0f, 0.0f }; + vtkm::Vec3f_32 BelowRangeColor = { 0.0f, 0.0f, 0.0f }; + vtkm::Vec3f_32 AboveRangeColor = { 0.0f, 0.0f, 0.0f }; + + bool UseClamping = true; + + std::vector ColorNodePos; + std::vector ColorRGB; + + std::vector OpacityNodePos; + std::vector OpacityAlpha; + std::vector OpacityMidSharp; + + vtkm::cont::ArrayHandle ColorPosHandle; + vtkm::cont::ArrayHandle ColorRGBHandle; + vtkm::cont::ArrayHandle OpacityPosHandle; + vtkm::cont::ArrayHandle OpacityAlphaHandle; + vtkm::cont::ArrayHandle OpacityMidSharpHandle; + bool ColorArraysChanged = true; + bool OpacityArraysChanged = true; + + vtkm::Id ModifiedCount = 1; + void Modified() { ++this->ModifiedCount; } + + void RecalculateRange() + { + vtkm::Range r; + if (this->ColorNodePos.size() > 0) + { + r.Include(this->ColorNodePos.front()); + r.Include(this->ColorNodePos.back()); + } + + if (this->OpacityNodePos.size() > 0) + { + r.Include(this->OpacityNodePos.front()); + r.Include(this->OpacityNodePos.back()); + } + + this->TableRange = r; + } +}; + +} // namespace detail + namespace internal { std::set GetPresetNames(); @@ -32,7 +298,7 @@ bool LoadColorTablePreset(std::string name, vtkm::cont::ColorTable& table); //---------------------------------------------------------------------------- ColorTable::ColorTable(vtkm::cont::ColorTable::Preset preset) - : Impl(std::make_shared()) + : Internals(std::make_shared()) { const bool loaded = this->LoadPreset(preset); if (!loaded) @@ -40,14 +306,15 @@ ColorTable::ColorTable(vtkm::cont::ColorTable::Preset preset) //so that the internal host side cache is constructed and we leave //the constructor in a valid state. We use LAB as it is the default //when the no parameter constructor is called - this->SetColorSpace(ColorSpace::LAB); + this->SetColorSpace(vtkm::ColorSpace::Lab); } - this->AddSegmentAlpha(this->Impl->TableRange.Min, 1.0f, this->Impl->TableRange.Max, 1.0f); + this->AddSegmentAlpha( + this->Internals->TableRange.Min, 1.0f, this->Internals->TableRange.Max, 1.0f); } //---------------------------------------------------------------------------- ColorTable::ColorTable(const std::string& name) - : Impl(std::make_shared()) + : Internals(std::make_shared()) { const bool loaded = this->LoadPreset(name); if (!loaded) @@ -55,24 +322,25 @@ ColorTable::ColorTable(const std::string& name) //so that the internal host side cache is constructed and we leave //the constructor in a valid state. We use LAB as it is the default //when the no parameter constructor is called - this->SetColorSpace(ColorSpace::LAB); + this->SetColorSpace(vtkm::ColorSpace::Lab); } - this->AddSegmentAlpha(this->Impl->TableRange.Min, 1.0f, this->Impl->TableRange.Max, 1.0f); + this->AddSegmentAlpha( + this->Internals->TableRange.Min, 1.0f, this->Internals->TableRange.Max, 1.0f); } //---------------------------------------------------------------------------- -ColorTable::ColorTable(ColorSpace space) - : Impl(std::make_shared()) +ColorTable::ColorTable(vtkm::ColorSpace space) + : Internals(std::make_shared()) { this->SetColorSpace(space); } //---------------------------------------------------------------------------- ColorTable::ColorTable(const vtkm::Range& range, - const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - ColorSpace space) - : Impl(std::make_shared()) + const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::ColorSpace space) + : Internals(std::make_shared()) { this->AddSegment(range.Min, rgb1, range.Max, rgb2); this->AddSegmentAlpha(range.Min, 1.0f, range.Max, 1.0f); @@ -81,13 +349,13 @@ ColorTable::ColorTable(const vtkm::Range& range, //---------------------------------------------------------------------------- ColorTable::ColorTable(const vtkm::Range& range, - const vtkm::Vec& rgba1, - const vtkm::Vec& rgba2, - ColorSpace space) - : Impl(std::make_shared()) + const vtkm::Vec4f_32& rgba1, + const vtkm::Vec4f_32& rgba2, + vtkm::ColorSpace space) + : Internals(std::make_shared()) { - vtkm::Vec rgb1(rgba1[0], rgba1[1], rgba1[2]); - vtkm::Vec rgb2(rgba2[0], rgba2[1], rgba2[2]); + vtkm::Vec3f_32 rgb1(rgba1[0], rgba1[1], rgba1[2]); + vtkm::Vec3f_32 rgb2(rgba2[0], rgba2[1], rgba2[2]); this->AddSegment(range.Min, rgb1, range.Max, rgb2); this->AddSegmentAlpha(range.Min, rgba1[3], range.Max, rgba2[3]); this->SetColorSpace(space); @@ -95,11 +363,11 @@ ColorTable::ColorTable(const vtkm::Range& range, //---------------------------------------------------------------------------- ColorTable::ColorTable(const std::string& name, - vtkm::cont::ColorSpace colorSpace, - const vtkm::Vec& nanColor, - const std::vector& rgbPoints, - const std::vector& alphaPoints) - : Impl(std::make_shared()) + vtkm::ColorSpace colorSpace, + const vtkm::Vec3f_64& nanColor, + const std::vector& rgbPoints, + const std::vector& alphaPoints) + : Internals(std::make_shared()) { this->SetName(name); this->SetColorSpace(colorSpace); @@ -115,13 +383,13 @@ ColorTable::~ColorTable() {} //---------------------------------------------------------------------------- const std::string& ColorTable::GetName() const { - return this->Impl->Name; + return this->Internals->Name; } //---------------------------------------------------------------------------- void ColorTable::SetName(const std::string& name) { - this->Impl->Name = name; + this->Internals->Name = name; } //---------------------------------------------------------------------------- @@ -145,129 +413,88 @@ bool ColorTable::LoadPreset(const std::string& name) //---------------------------------------------------------------------------- ColorTable ColorTable::MakeDeepCopy() { - ColorTable dcopy(this->Impl->CSpace); + ColorTable dcopy(this->Internals->Space); - dcopy.Impl->TableRange = this->Impl->TableRange; + dcopy.Internals->TableRange = this->Internals->TableRange; - dcopy.Impl->HostSideCache->NaNColor = this->Impl->HostSideCache->NaNColor; - dcopy.Impl->HostSideCache->BelowRangeColor = this->Impl->HostSideCache->BelowRangeColor; - dcopy.Impl->HostSideCache->AboveRangeColor = this->Impl->HostSideCache->AboveRangeColor; + dcopy.Internals->NaNColor = this->Internals->NaNColor; + dcopy.Internals->BelowRangeColor = this->Internals->BelowRangeColor; + dcopy.Internals->AboveRangeColor = this->Internals->AboveRangeColor; - dcopy.Impl->HostSideCache->UseClamping = this->Impl->HostSideCache->UseClamping; + dcopy.Internals->UseClamping = this->Internals->UseClamping; - dcopy.Impl->ColorNodePos = this->Impl->ColorNodePos; - dcopy.Impl->ColorRGB = this->Impl->ColorRGB; + dcopy.Internals->ColorNodePos = this->Internals->ColorNodePos; + dcopy.Internals->ColorRGB = this->Internals->ColorRGB; - dcopy.Impl->OpacityNodePos = this->Impl->OpacityNodePos; - dcopy.Impl->OpacityAlpha = this->Impl->OpacityAlpha; - dcopy.Impl->OpacityMidSharp = this->Impl->OpacityMidSharp; + dcopy.Internals->OpacityNodePos = this->Internals->OpacityNodePos; + dcopy.Internals->OpacityAlpha = this->Internals->OpacityAlpha; + dcopy.Internals->OpacityMidSharp = this->Internals->OpacityMidSharp; return dcopy; } //---------------------------------------------------------------------------- -ColorSpace ColorTable::GetColorSpace() const +vtkm::ColorSpace ColorTable::GetColorSpace() const { - return this->Impl->CSpace; + return this->Internals->Space; } //---------------------------------------------------------------------------- -void ColorTable::SetColorSpace(ColorSpace space) +void ColorTable::SetColorSpace(vtkm::ColorSpace space) { - - if (this->Impl->CSpace != space || this->Impl->HostSideCache.get() == nullptr) - { - this->Impl->HostSideCacheChanged = true; - this->Impl->CSpace = space; - //Remove any existing host information - - switch (space) - { - case vtkm::cont::ColorSpace::RGB: - { - auto* hostPortal = new vtkm::exec::ColorTableRGB(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::HSV: - { - auto* hostPortal = new vtkm::exec::ColorTableHSV(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::HSV_WRAP: - { - auto* hostPortal = new vtkm::exec::ColorTableHSVWrap(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::LAB: - { - auto* hostPortal = new vtkm::exec::ColorTableLab(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - case vtkm::cont::ColorSpace::DIVERGING: - { - auto* hostPortal = new vtkm::exec::ColorTableDiverging(); - this->Impl->HostSideCache.reset(hostPortal); - break; - } - default: - throw vtkm::cont::ErrorBadType("unknown vtkm::cont::ColorType requested"); - } - } + this->Internals->Space = space; + this->Internals->Modified(); } //---------------------------------------------------------------------------- void ColorTable::SetClamping(bool state) { - this->Impl->HostSideCache->UseClamping = state; - this->Impl->HostSideCache->Modified(); + this->Internals->UseClamping = state; + this->Internals->Modified(); } //---------------------------------------------------------------------------- bool ColorTable::GetClamping() const { - return this->Impl->HostSideCache->UseClamping; + return this->Internals->UseClamping; } //---------------------------------------------------------------------------- -void ColorTable::SetBelowRangeColor(const vtkm::Vec& c) +void ColorTable::SetBelowRangeColor(const vtkm::Vec3f_32& c) { - this->Impl->HostSideCache->BelowRangeColor = c; - this->Impl->HostSideCache->Modified(); + this->Internals->BelowRangeColor = c; + this->Internals->Modified(); } //---------------------------------------------------------------------------- -const vtkm::Vec& ColorTable::GetBelowRangeColor() const +const vtkm::Vec3f_32& ColorTable::GetBelowRangeColor() const { - return this->Impl->HostSideCache->BelowRangeColor; + return this->Internals->BelowRangeColor; } //---------------------------------------------------------------------------- -void ColorTable::SetAboveRangeColor(const vtkm::Vec& c) +void ColorTable::SetAboveRangeColor(const vtkm::Vec3f_32& c) { - this->Impl->HostSideCache->AboveRangeColor = c; - this->Impl->HostSideCache->Modified(); + this->Internals->AboveRangeColor = c; + this->Internals->Modified(); } //---------------------------------------------------------------------------- -const vtkm::Vec& ColorTable::GetAboveRangeColor() const +const vtkm::Vec3f_32& ColorTable::GetAboveRangeColor() const { - return this->Impl->HostSideCache->AboveRangeColor; + return this->Internals->AboveRangeColor; } //---------------------------------------------------------------------------- -void ColorTable::SetNaNColor(const vtkm::Vec& c) +void ColorTable::SetNaNColor(const vtkm::Vec3f_32& c) { - this->Impl->HostSideCache->NaNColor = c; - this->Impl->HostSideCache->Modified(); + this->Internals->NaNColor = c; + this->Internals->Modified(); } //---------------------------------------------------------------------------- -const vtkm::Vec& ColorTable::GetNaNColor() const +const vtkm::Vec3f_32& ColorTable::GetNaNColor() const { - return this->Impl->HostSideCache->NaNColor; + return this->Internals->NaNColor; } //---------------------------------------------------------------------------- @@ -280,40 +507,45 @@ void ColorTable::Clear() //--------------------------------------------------------------------------- void ColorTable::ClearColors() { - this->Impl->ColorNodePos.clear(); - this->Impl->ColorRGB.clear(); - this->Impl->ColorArraysChanged = true; + this->Internals->ColorNodePos.clear(); + this->Internals->ColorRGB.clear(); + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- void ColorTable::ClearAlpha() { - this->Impl->OpacityNodePos.clear(); - this->Impl->OpacityAlpha.clear(); - this->Impl->OpacityMidSharp.clear(); - this->Impl->OpacityArraysChanged = true; + this->Internals->OpacityNodePos.clear(); + this->Internals->OpacityAlpha.clear(); + this->Internals->OpacityMidSharp.clear(); + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- void ColorTable::ReverseColors() { - std::reverse(this->Impl->ColorRGB.begin(), this->Impl->ColorRGB.end()); - this->Impl->ColorArraysChanged = true; + std::reverse(this->Internals->ColorRGB.begin(), this->Internals->ColorRGB.end()); + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- void ColorTable::ReverseAlpha() { - std::reverse(this->Impl->OpacityAlpha.begin(), this->Impl->OpacityAlpha.end()); + std::reverse(this->Internals->OpacityAlpha.begin(), this->Internals->OpacityAlpha.end()); //To keep the shape correct the mid and sharp values of the last node are not included in the reversal - std::reverse(this->Impl->OpacityMidSharp.begin(), this->Impl->OpacityMidSharp.end() - 1); - this->Impl->OpacityArraysChanged = true; + std::reverse(this->Internals->OpacityMidSharp.begin(), + this->Internals->OpacityMidSharp.end() - 1); + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); } //--------------------------------------------------------------------------- const vtkm::Range& ColorTable::GetRange() const { - return this->Impl->TableRange; + return this->Internals->TableRange; } //--------------------------------------------------------------------------- @@ -327,29 +559,32 @@ void ColorTable::RescaleToRange(const vtkm::Range& r) auto newRange = adjustRange(r); //slam control points down to 0.0 - 1.0, and than rescale to new range - const double minv = this->GetRange().Min; - const double oldScale = this->GetRange().Length(); - const double newScale = newRange.Length(); + const vtkm::Float64 minv = this->GetRange().Min; + const vtkm::Float64 oldScale = this->GetRange().Length(); + const vtkm::Float64 newScale = newRange.Length(); VTKM_ASSERT(oldScale > 0); VTKM_ASSERT(newScale > 0); - for (auto i = this->Impl->ColorNodePos.begin(); i != this->Impl->ColorNodePos.end(); ++i) + for (auto i = this->Internals->ColorNodePos.begin(); i != this->Internals->ColorNodePos.end(); + ++i) { const auto t = (*i - minv) / oldScale; *i = (t * newScale) + newRange.Min; } - for (auto i = this->Impl->OpacityNodePos.begin(); i != this->Impl->OpacityNodePos.end(); ++i) + for (auto i = this->Internals->OpacityNodePos.begin(); i != this->Internals->OpacityNodePos.end(); + ++i) { const auto t = (*i - minv) / oldScale; *i = (t * newScale) + newRange.Min; } - this->Impl->ColorArraysChanged = true; - this->Impl->OpacityArraysChanged = true; - this->Impl->TableRange = newRange; + this->Internals->ColorArraysChanged = true; + this->Internals->OpacityArraysChanged = true; + this->Internals->TableRange = newRange; + this->Internals->Modified(); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddPoint(double x, const vtkm::Vec& rgb) +vtkm::Int32 ColorTable::AddPoint(vtkm::Float64 x, const vtkm::Vec3f_32& rgb) { if (outside_range(rgb)) { @@ -357,50 +592,52 @@ vtkm::Int32 ColorTable::AddPoint(double x, const vtkm::Vec& rgb) } std::size_t index = 0; - if (this->Impl->ColorNodePos.size() == 0 || this->Impl->ColorNodePos.back() < x) + if (this->Internals->ColorNodePos.size() == 0 || this->Internals->ColorNodePos.back() < x) { - this->Impl->ColorNodePos.emplace_back(x); - this->Impl->ColorRGB.emplace_back(rgb); - index = this->Impl->ColorNodePos.size(); + this->Internals->ColorNodePos.emplace_back(x); + this->Internals->ColorRGB.emplace_back(rgb); + index = this->Internals->ColorNodePos.size(); } else { - auto begin = this->Impl->ColorNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->ColorNodePos.end(), x); + auto begin = this->Internals->ColorNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->ColorNodePos.end(), x); index = static_cast(std::distance(begin, pos)); if (*pos == x) { - this->Impl->ColorRGB[index] = rgb; + this->Internals->ColorRGB[index] = rgb; } else { - this->Impl->ColorRGB.emplace(this->Impl->ColorRGB.begin() + std::distance(begin, pos), rgb); - this->Impl->ColorNodePos.emplace(pos, x); + this->Internals->ColorRGB.emplace( + this->Internals->ColorRGB.begin() + std::distance(begin, pos), rgb); + this->Internals->ColorNodePos.emplace(pos, x); } } - this->Impl->TableRange.Include(x); //update range to include x - this->Impl->ColorArraysChanged = true; + this->Internals->TableRange.Include(x); //update range to include x + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); return static_cast(index); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddPointHSV(double x, const vtkm::Vec& hsv) +vtkm::Int32 ColorTable::AddPointHSV(vtkm::Float64 x, const vtkm::Vec3f_32& hsv) { return this->AddPoint(x, hsvTorgb(hsv)); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddSegment(double x1, - const vtkm::Vec& rgb1, - double x2, - const vtkm::Vec& rgb2) +vtkm::Int32 ColorTable::AddSegment(vtkm::Float64 x1, + const vtkm::Vec3f_32& rgb1, + vtkm::Float64 x2, + const vtkm::Vec3f_32& rgb2) { if (outside_range(rgb1, rgb2)) { return -1; } - if (this->Impl->ColorNodePos.size() > 0) + if (this->Internals->ColorNodePos.size() > 0) { //Todo: // - This could be optimized so we do 2 less lower_bound calls when @@ -408,10 +645,10 @@ vtkm::Int32 ColorTable::AddSegment(double x1, //When we add a segment we remove all points that are inside the line - auto nodeBegin = this->Impl->ColorNodePos.begin(); - auto nodeEnd = this->Impl->ColorNodePos.end(); + auto nodeBegin = this->Internals->ColorNodePos.begin(); + auto nodeEnd = this->Internals->ColorNodePos.end(); - auto rgbBegin = this->Impl->ColorRGB.begin(); + auto rgbBegin = this->Internals->ColorRGB.begin(); auto nodeStart = std::lower_bound(nodeBegin, nodeEnd, x1); auto nodeStop = std::lower_bound(nodeBegin, nodeEnd, x2); @@ -421,8 +658,8 @@ vtkm::Int32 ColorTable::AddSegment(double x1, //erase is exclusive so if end->x == x2 it will be kept around, and //than we will update it in AddPoint - this->Impl->ColorNodePos.erase(nodeStart, nodeStop); - this->Impl->ColorRGB.erase(rgbStart, rgbStop); + this->Internals->ColorNodePos.erase(nodeStart, nodeStop); + this->Internals->ColorRGB.erase(rgbStart, rgbStop); } vtkm::Int32 pos = this->AddPoint(x1, rgb1); this->AddPoint(x2, rgb2); @@ -430,26 +667,26 @@ vtkm::Int32 ColorTable::AddSegment(double x1, } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddSegmentHSV(double x1, - const vtkm::Vec& hsv1, - double x2, - const vtkm::Vec& hsv2) +vtkm::Int32 ColorTable::AddSegmentHSV(vtkm::Float64 x1, + const vtkm::Vec3f_32& hsv1, + vtkm::Float64 x2, + const vtkm::Vec3f_32& hsv2) { return this->AddSegment(x1, hsvTorgb(hsv1), x2, hsvTorgb(hsv2)); } //--------------------------------------------------------------------------- -bool ColorTable::GetPoint(vtkm::Int32 index, vtkm::Vec& data) const +bool ColorTable::GetPoint(vtkm::Int32 index, vtkm::Vec4f_64& data) const { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->ColorNodePos.size(); + const std::size_t size = this->Internals->ColorNodePos.size(); if (index < 0 || i >= size) { return false; } - const auto& pos = this->Impl->ColorNodePos[i]; - const auto& rgb = this->Impl->ColorRGB[i]; + const auto& pos = this->Internals->ColorNodePos[i]; + const auto& rgb = this->Internals->ColorRGB[i]; data[0] = pos; data[1] = rgb[0]; @@ -459,7 +696,7 @@ bool ColorTable::GetPoint(vtkm::Int32 index, vtkm::Vec& data) const } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::Vec& data) +vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::Vec4f_64& data) { //skip data[0] as we don't care about position if (outside_range(data[1], data[2], data[3])) @@ -468,7 +705,7 @@ vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::Vec(index); - const std::size_t size = this->Impl->ColorNodePos.size(); + const std::size_t size = this->Internals->ColorNodePos.size(); if (index < 0 || i >= size) { return -1; @@ -476,33 +713,35 @@ vtkm::Int32 ColorTable::UpdatePoint(vtkm::Int32 index, const vtkm::VecImpl->ColorNodePos.begin() + index; - auto newPos = - std::lower_bound(this->Impl->ColorNodePos.begin(), this->Impl->ColorNodePos.end(), data[0]); + auto oldPos = this->Internals->ColorNodePos.begin() + index; + auto newPos = std::lower_bound( + this->Internals->ColorNodePos.begin(), this->Internals->ColorNodePos.end(), data[0]); if (oldPos == newPos) { //node's relative location hasn't changed - this->Impl->ColorArraysChanged = true; - auto& rgb = this->Impl->ColorRGB[i]; + this->Internals->ColorArraysChanged = true; + auto& rgb = this->Internals->ColorRGB[i]; *newPos = data[0]; - rgb[0] = static_cast(data[1]); - rgb[1] = static_cast(data[2]); - rgb[2] = static_cast(data[3]); + rgb[0] = static_cast(data[1]); + rgb[1] = static_cast(data[2]); + rgb[2] = static_cast(data[3]); + this->Internals->Modified(); return index; } else { //remove the point, and add the new values as the relative location is different this->RemovePoint(index); - vtkm::Vec newrgb( - static_cast(data[1]), static_cast(data[2]), static_cast(data[3])); + vtkm::Vec3f_32 newrgb(static_cast(data[1]), + static_cast(data[2]), + static_cast(data[3])); return this->AddPoint(data[0], newrgb); } } //--------------------------------------------------------------------------- -bool ColorTable::RemovePoint(double x) +bool ColorTable::RemovePoint(vtkm::Float64 x) { - auto begin = this->Impl->ColorNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->ColorNodePos.end(), x); + auto begin = this->Internals->ColorNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->ColorNodePos.end(), x); return this->RemovePoint(static_cast(std::distance(begin, pos))); } @@ -510,80 +749,85 @@ bool ColorTable::RemovePoint(double x) bool ColorTable::RemovePoint(vtkm::Int32 index) { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->ColorNodePos.size(); + const std::size_t size = this->Internals->ColorNodePos.size(); if (index < 0 || i >= size) { return false; } - this->Impl->ColorNodePos.erase(this->Impl->ColorNodePos.begin() + index); - this->Impl->ColorRGB.erase(this->Impl->ColorRGB.begin() + index); - this->Impl->ColorArraysChanged = true; - this->Impl->RecalculateRange(); + this->Internals->ColorNodePos.erase(this->Internals->ColorNodePos.begin() + index); + this->Internals->ColorRGB.erase(this->Internals->ColorRGB.begin() + index); + this->Internals->ColorArraysChanged = true; + this->Internals->RecalculateRange(); + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- vtkm::Int32 ColorTable::GetNumberOfPoints() const { - return static_cast(this->Impl->ColorNodePos.size()); + return static_cast(this->Internals->ColorNodePos.size()); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddPointAlpha(double x, float alpha, float midpoint, float sharpness) +vtkm::Int32 ColorTable::AddPointAlpha(vtkm::Float64 x, + vtkm::Float32 alpha, + vtkm::Float32 midpoint, + vtkm::Float32 sharpness) { if (outside_range(alpha, midpoint, sharpness)) { return -1; } - const vtkm::Vec midsharp(midpoint, sharpness); + const vtkm::Vec2f_32 midsharp(midpoint, sharpness); std::size_t index = 0; - if (this->Impl->OpacityNodePos.size() == 0 || this->Impl->OpacityNodePos.back() < x) + if (this->Internals->OpacityNodePos.size() == 0 || this->Internals->OpacityNodePos.back() < x) { - this->Impl->OpacityNodePos.emplace_back(x); - this->Impl->OpacityAlpha.emplace_back(alpha); - this->Impl->OpacityMidSharp.emplace_back(midsharp); - index = this->Impl->OpacityNodePos.size(); + this->Internals->OpacityNodePos.emplace_back(x); + this->Internals->OpacityAlpha.emplace_back(alpha); + this->Internals->OpacityMidSharp.emplace_back(midsharp); + index = this->Internals->OpacityNodePos.size(); } else { - auto begin = this->Impl->OpacityNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->OpacityNodePos.end(), x); + auto begin = this->Internals->OpacityNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->OpacityNodePos.end(), x); index = static_cast(std::distance(begin, pos)); if (*pos == x) { - this->Impl->OpacityAlpha[index] = alpha; - this->Impl->OpacityMidSharp[index] = midsharp; + this->Internals->OpacityAlpha[index] = alpha; + this->Internals->OpacityMidSharp[index] = midsharp; } else { - this->Impl->OpacityAlpha.emplace(this->Impl->OpacityAlpha.begin() + std::distance(begin, pos), - alpha); - this->Impl->OpacityMidSharp.emplace( - this->Impl->OpacityMidSharp.begin() + std::distance(begin, pos), midsharp); - this->Impl->OpacityNodePos.emplace(pos, x); + this->Internals->OpacityAlpha.emplace( + this->Internals->OpacityAlpha.begin() + std::distance(begin, pos), alpha); + this->Internals->OpacityMidSharp.emplace( + this->Internals->OpacityMidSharp.begin() + std::distance(begin, pos), midsharp); + this->Internals->OpacityNodePos.emplace(pos, x); } } - this->Impl->OpacityArraysChanged = true; - this->Impl->TableRange.Include(x); //update range to include x + this->Internals->OpacityArraysChanged = true; + this->Internals->TableRange.Include(x); //update range to include x + this->Internals->Modified(); return static_cast(index); } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, - float alpha1, - double x2, - float alpha2, - const vtkm::Vec& mid_sharp1, - const vtkm::Vec& mid_sharp2) +vtkm::Int32 ColorTable::AddSegmentAlpha(vtkm::Float64 x1, + vtkm::Float32 alpha1, + vtkm::Float64 x2, + vtkm::Float32 alpha2, + const vtkm::Vec2f_32& mid_sharp1, + const vtkm::Vec2f_32& mid_sharp2) { if (outside_range(alpha1, alpha2, mid_sharp1, mid_sharp2)) { return -1; } - if (this->Impl->OpacityNodePos.size() > 0) + if (this->Internals->OpacityNodePos.size() > 0) { //Todo: // - This could be optimized so we do 2 less lower_bound calls when @@ -591,11 +835,11 @@ vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, //When we add a segment we remove all points that are inside the line - auto nodeBegin = this->Impl->OpacityNodePos.begin(); - auto nodeEnd = this->Impl->OpacityNodePos.end(); + auto nodeBegin = this->Internals->OpacityNodePos.begin(); + auto nodeEnd = this->Internals->OpacityNodePos.end(); - auto alphaBegin = this->Impl->OpacityAlpha.begin(); - auto midBegin = this->Impl->OpacityMidSharp.begin(); + auto alphaBegin = this->Internals->OpacityAlpha.begin(); + auto midBegin = this->Internals->OpacityMidSharp.begin(); auto nodeStart = std::lower_bound(nodeBegin, nodeEnd, x1); auto nodeStop = std::lower_bound(nodeBegin, nodeEnd, x2); @@ -607,9 +851,9 @@ vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, //erase is exclusive so if end->x == x2 it will be kept around, and //than we will update it in AddPoint - this->Impl->OpacityNodePos.erase(nodeStart, nodeStop); - this->Impl->OpacityAlpha.erase(alphaStart, alphaStop); - this->Impl->OpacityMidSharp.erase(midStart, midStop); + this->Internals->OpacityNodePos.erase(nodeStart, nodeStop); + this->Internals->OpacityAlpha.erase(alphaStart, alphaStop); + this->Internals->OpacityMidSharp.erase(midStart, midStop); } vtkm::Int32 pos = this->AddPointAlpha(x1, alpha1, mid_sharp1[0], mid_sharp1[1]); @@ -618,18 +862,18 @@ vtkm::Int32 ColorTable::AddSegmentAlpha(double x1, } //--------------------------------------------------------------------------- -bool ColorTable::GetPointAlpha(vtkm::Int32 index, vtkm::Vec& data) const +bool ColorTable::GetPointAlpha(vtkm::Int32 index, vtkm::Vec4f_64& data) const { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->OpacityNodePos.size(); + const std::size_t size = this->Internals->OpacityNodePos.size(); if (index < 0 || i >= size) { return false; } - const auto& pos = this->Impl->OpacityNodePos[i]; - const auto& alpha = this->Impl->OpacityAlpha[i]; - const auto& midsharp = this->Impl->OpacityMidSharp[i]; + const auto& pos = this->Internals->OpacityNodePos[i]; + const auto& alpha = this->Internals->OpacityAlpha[i]; + const auto& midsharp = this->Internals->OpacityMidSharp[i]; data[0] = pos; data[1] = alpha; @@ -639,7 +883,7 @@ bool ColorTable::GetPointAlpha(vtkm::Int32 index, vtkm::Vec& data) co } //--------------------------------------------------------------------------- -vtkm::Int32 ColorTable::UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec& data) +vtkm::Int32 ColorTable::UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec4f_64& data) { //skip data[0] as we don't care about position if (outside_range(data[1], data[2], data[3])) @@ -648,42 +892,43 @@ vtkm::Int32 ColorTable::UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec(index); - const std::size_t size = this->Impl->OpacityNodePos.size(); + const std::size_t size = this->Internals->OpacityNodePos.size(); if (index < 0 || i >= size) { return -1; } //When updating the first question is has the relative position of the point changed? //If it hasn't we can quickly just update the RGB value - auto oldPos = this->Impl->OpacityNodePos.begin() + index; - auto newPos = - std::lower_bound(this->Impl->OpacityNodePos.begin(), this->Impl->OpacityNodePos.end(), data[0]); + auto oldPos = this->Internals->OpacityNodePos.begin() + index; + auto newPos = std::lower_bound( + this->Internals->OpacityNodePos.begin(), this->Internals->OpacityNodePos.end(), data[0]); if (oldPos == newPos) { //node's relative location hasn't changed - this->Impl->OpacityArraysChanged = true; - auto& alpha = this->Impl->OpacityAlpha[i]; - auto& midsharp = this->Impl->OpacityMidSharp[i]; + this->Internals->OpacityArraysChanged = true; + auto& alpha = this->Internals->OpacityAlpha[i]; + auto& midsharp = this->Internals->OpacityMidSharp[i]; *newPos = data[0]; - alpha = static_cast(data[1]); - midsharp[0] = static_cast(data[2]); - midsharp[1] = static_cast(data[3]); + alpha = static_cast(data[1]); + midsharp[0] = static_cast(data[2]); + midsharp[1] = static_cast(data[3]); + this->Internals->Modified(); return index; } else { //remove the point, and add the new values as the relative location is different this->RemovePointAlpha(index); return this->AddPointAlpha(data[0], - static_cast(data[1]), - static_cast(data[2]), - static_cast(data[3])); + static_cast(data[1]), + static_cast(data[2]), + static_cast(data[3])); } } //--------------------------------------------------------------------------- -bool ColorTable::RemovePointAlpha(double x) +bool ColorTable::RemovePointAlpha(vtkm::Float64 x) { - auto begin = this->Impl->OpacityNodePos.begin(); - auto pos = std::lower_bound(begin, this->Impl->OpacityNodePos.end(), x); + auto begin = this->Internals->OpacityNodePos.begin(); + auto pos = std::lower_bound(begin, this->Internals->OpacityNodePos.end(), x); return this->RemovePointAlpha(static_cast(std::distance(begin, pos))); } @@ -691,28 +936,29 @@ bool ColorTable::RemovePointAlpha(double x) bool ColorTable::RemovePointAlpha(vtkm::Int32 index) { std::size_t i = static_cast(index); - const std::size_t size = this->Impl->OpacityNodePos.size(); + const std::size_t size = this->Internals->OpacityNodePos.size(); if (index < 0 || i >= size) { return false; } - this->Impl->OpacityNodePos.erase(this->Impl->OpacityNodePos.begin() + index); - this->Impl->OpacityAlpha.erase(this->Impl->OpacityAlpha.begin() + index); - this->Impl->OpacityMidSharp.erase(this->Impl->OpacityMidSharp.begin() + index); - this->Impl->OpacityArraysChanged = true; - this->Impl->RecalculateRange(); + this->Internals->OpacityNodePos.erase(this->Internals->OpacityNodePos.begin() + index); + this->Internals->OpacityAlpha.erase(this->Internals->OpacityAlpha.begin() + index); + this->Internals->OpacityMidSharp.erase(this->Internals->OpacityMidSharp.begin() + index); + this->Internals->OpacityArraysChanged = true; + this->Internals->RecalculateRange(); + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- vtkm::Int32 ColorTable::GetNumberOfPointsAlpha() const { - return static_cast(this->Impl->OpacityNodePos.size()); + return static_cast(this->Internals->OpacityNodePos.size()); } //--------------------------------------------------------------------------- -bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr) +bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr) { if (n <= 0 || ptr == nullptr) { @@ -721,22 +967,24 @@ bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr) this->ClearColors(); std::size_t size = static_cast(n / 4); - this->Impl->ColorNodePos.reserve(size); - this->Impl->ColorRGB.reserve(size); + this->Internals->ColorNodePos.reserve(size); + this->Internals->ColorRGB.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays - vtkm::Vec rgb( - static_cast(ptr[1]), static_cast(ptr[2]), static_cast(ptr[3])); + vtkm::Vec3f_32 rgb(static_cast(ptr[1]), + static_cast(ptr[2]), + static_cast(ptr[3])); this->AddPoint(ptr[0], rgb); ptr += 4; } - this->Impl->ColorArraysChanged = true; + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- -bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr) +bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr) { if (n <= 0 || ptr == nullptr) { @@ -745,20 +993,21 @@ bool ColorTable::FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr) this->ClearColors(); std::size_t size = static_cast(n / 4); - this->Impl->ColorNodePos.reserve(size); - this->Impl->ColorRGB.reserve(size); + this->Internals->ColorNodePos.reserve(size); + this->Internals->ColorRGB.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays - vtkm::Vec rgb(ptr[1], ptr[2], ptr[3]); + vtkm::Vec3f_32 rgb(ptr[1], ptr[2], ptr[3]); this->AddPoint(ptr[0], rgb); ptr += 4; } - this->Impl->ColorArraysChanged = true; + this->Internals->ColorArraysChanged = true; + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- -bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* ptr) +bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr) { if (n <= 0 || ptr == nullptr) { @@ -767,22 +1016,25 @@ bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* pt this->ClearAlpha(); std::size_t size = static_cast(n / 4); - this->Impl->OpacityNodePos.reserve(size); - this->Impl->OpacityAlpha.reserve(size); - this->Impl->OpacityMidSharp.reserve(size); + this->Internals->OpacityNodePos.reserve(size); + this->Internals->OpacityAlpha.reserve(size); + this->Internals->OpacityMidSharp.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays - this->AddPointAlpha( - ptr[0], static_cast(ptr[1]), static_cast(ptr[2]), static_cast(ptr[3])); + this->AddPointAlpha(ptr[0], + static_cast(ptr[1]), + static_cast(ptr[2]), + static_cast(ptr[3])); ptr += 4; } - this->Impl->OpacityArraysChanged = true; + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); return true; } //--------------------------------------------------------------------------- -bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr) +bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr) { if (n <= 0 || ptr == nullptr) { @@ -792,87 +1044,95 @@ bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr std::size_t size = static_cast(n / 4); - this->Impl->OpacityNodePos.reserve(size); - this->Impl->OpacityAlpha.reserve(size); - this->Impl->OpacityMidSharp.reserve(size); + this->Internals->OpacityNodePos.reserve(size); + this->Internals->OpacityAlpha.reserve(size); + this->Internals->OpacityMidSharp.reserve(size); for (std::size_t i = 0; i < size; ++i) { //allows us to support unsorted arrays this->AddPointAlpha(ptr[0], ptr[1], ptr[2], ptr[3]); ptr += 4; } - this->Impl->OpacityArraysChanged = true; + this->Internals->OpacityArraysChanged = true; + this->Internals->Modified(); return true; } +//---------------------------------------------------------------------------- +void ColorTable::UpdateArrayHandles() const +{ + //Only rebuild the array handles that have changed since the last time + //we have modified or color / opacity information + + if (this->Internals->ColorArraysChanged) + { + this->Internals->ColorPosHandle = + vtkm::cont::make_ArrayHandle(this->Internals->ColorNodePos, vtkm::CopyFlag::Off); + this->Internals->ColorRGBHandle = + vtkm::cont::make_ArrayHandle(this->Internals->ColorRGB, vtkm::CopyFlag::Off); + this->Internals->ColorArraysChanged = false; + } + + if (this->Internals->OpacityArraysChanged) + { + this->Internals->OpacityPosHandle = + vtkm::cont::make_ArrayHandle(this->Internals->OpacityNodePos, vtkm::CopyFlag::Off); + this->Internals->OpacityAlphaHandle = + vtkm::cont::make_ArrayHandle(this->Internals->OpacityAlpha, vtkm::CopyFlag::Off); + this->Internals->OpacityMidSharpHandle = + vtkm::cont::make_ArrayHandle(this->Internals->OpacityMidSharp, vtkm::CopyFlag::Off); + this->Internals->OpacityArraysChanged = false; + } +} + +//--------------------------------------------------------------------------- +vtkm::exec::ColorTable ColorTable::PrepareForExecution(vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) const +{ + this->UpdateArrayHandles(); + + vtkm::exec::ColorTable execTable; + + execTable.Space = this->Internals->Space; + execTable.NaNColor = this->Internals->NaNColor; + execTable.BelowRangeColor = this->Internals->BelowRangeColor; + execTable.AboveRangeColor = this->Internals->AboveRangeColor; + execTable.UseClamping = this->Internals->UseClamping; + + VTKM_ASSERT(static_cast(this->Internals->ColorNodePos.size()) == + this->Internals->ColorPosHandle.GetNumberOfValues()); + execTable.ColorSize = + static_cast(this->Internals->ColorPosHandle.GetNumberOfValues()); + VTKM_ASSERT(static_cast(execTable.ColorSize) == + this->Internals->ColorRGBHandle.GetNumberOfValues()); + execTable.ColorNodes = this->Internals->ColorPosHandle.PrepareForInput(device, token).GetArray(); + execTable.RGB = this->Internals->ColorRGBHandle.PrepareForInput(device, token).GetArray(); + + VTKM_ASSERT(static_cast(this->Internals->OpacityNodePos.size()) == + this->Internals->OpacityPosHandle.GetNumberOfValues()); + execTable.OpacitySize = + static_cast(this->Internals->OpacityPosHandle.GetNumberOfValues()); + VTKM_ASSERT(static_cast(execTable.OpacitySize) == + this->Internals->OpacityAlphaHandle.GetNumberOfValues()); + VTKM_ASSERT(static_cast(execTable.OpacitySize) == + this->Internals->OpacityMidSharpHandle.GetNumberOfValues()); + execTable.ONodes = this->Internals->OpacityPosHandle.PrepareForInput(device, token).GetArray(); + execTable.Alpha = this->Internals->OpacityAlphaHandle.PrepareForInput(device, token).GetArray(); + execTable.MidSharp = + this->Internals->OpacityMidSharpHandle.PrepareForInput(device, token).GetArray(); + + return execTable; +} + +vtkm::exec::ColorTable ColorTable::PrepareForExecution(vtkm::cont::DeviceAdapterId device) const +{ + vtkm::cont::Token token; + return this->PrepareForExecution(device, token); +} + //--------------------------------------------------------------------------- vtkm::Id ColorTable::GetModifiedCount() const { - return this->Impl->HostSideCache->GetModifiedCount(); -} - -//---------------------------------------------------------------------------- -bool ColorTable::NeedToCreateExecutionColorTable() const -{ - return this->Impl->HostSideCacheChanged; -} - -//---------------------------------------------------------------------------- -void ColorTable::UpdateExecutionColorTable( - vtkm::cont::VirtualObjectHandle* handle) const -{ - this->Impl->ExecHandle.reset(handle); -} - -//---------------------------------------------------------------------------- -ColorTable::TransferState ColorTable::GetExecutionDataForTransfer() const -{ - //Only rebuild the array handles that have changed since the last time - //we have modified or color / opacity information - - if (this->Impl->ColorArraysChanged) - { - this->Impl->ColorPosHandle = - vtkm::cont::make_ArrayHandle(this->Impl->ColorNodePos, vtkm::CopyFlag::Off); - this->Impl->ColorRGBHandle = - vtkm::cont::make_ArrayHandle(this->Impl->ColorRGB, vtkm::CopyFlag::Off); - } - - if (this->Impl->OpacityArraysChanged) - { - this->Impl->OpacityPosHandle = - vtkm::cont::make_ArrayHandle(this->Impl->OpacityNodePos, vtkm::CopyFlag::Off); - this->Impl->OpacityAlphaHandle = - vtkm::cont::make_ArrayHandle(this->Impl->OpacityAlpha, vtkm::CopyFlag::Off); - this->Impl->OpacityMidSharpHandle = - vtkm::cont::make_ArrayHandle(this->Impl->OpacityMidSharp, vtkm::CopyFlag::Off); - } - - TransferState state = { (this->Impl->ColorArraysChanged || this->Impl->OpacityArraysChanged || - this->Impl->HostSideCacheChanged), - this->Impl->HostSideCache.get(), - this->Impl->ColorPosHandle, - this->Impl->ColorRGBHandle, - this->Impl->OpacityPosHandle, - this->Impl->OpacityAlphaHandle, - this->Impl->OpacityMidSharpHandle }; - - this->Impl->ColorArraysChanged = false; - this->Impl->OpacityArraysChanged = false; - this->Impl->HostSideCacheChanged = false; - return state; -} - -//---------------------------------------------------------------------------- -vtkm::exec::ColorTableBase* ColorTable::GetControlRepresentation() const -{ - return this->Impl->HostSideCache.get(); -} - -//---------------------------------------------------------------------------- -vtkm::cont::VirtualObjectHandle const* ColorTable::GetExecutionHandle() - const -{ - return this->Impl->ExecHandle.get(); + return this->Internals->ModifiedCount; } } } //namespace vtkm::cont diff --git a/vtkm/cont/ColorTable.h b/vtkm/cont/ColorTable.h index fd839954c..37cca608b 100644 --- a/vtkm/cont/ColorTable.h +++ b/vtkm/cont/ColorTable.h @@ -17,43 +17,35 @@ #include #include +#include + +#include #include namespace vtkm { - -namespace exec -{ -//forward declare exec objects -class ColorTableBase; -} - namespace cont { -template -class VirtualObjectHandle; - - namespace detail { struct ColorTableInternals; } -enum struct ColorSpace +struct VTKM_DEPRECATED(1.6, "Use vtkm::ColorSpace.") ColorSpace { - RGB, - HSV, - HSV_WRAP, - LAB, - DIVERGING + static constexpr vtkm::ColorSpace RGB = vtkm::ColorSpace::RGB; + static constexpr vtkm::ColorSpace HSV = vtkm::ColorSpace::HSV; + static constexpr vtkm::ColorSpace HSV_WRAP = vtkm::ColorSpace::HSVWrap; + static constexpr vtkm::ColorSpace LAB = vtkm::ColorSpace::Lab; + static constexpr vtkm::ColorSpace DIVERGING = vtkm::ColorSpace::Diverging; }; /// \brief Color Table for coloring arbitrary fields /// /// -/// The vtkm::cont::ColorTable allows for color mapping in RGB or HSV space and +/// The `vtkm::cont::ColorTable` allows for color mapping in RGB or HSV space and /// uses a piecewise hermite functions to allow opacity interpolation that can be /// piecewise constant, piecewise linear, or somewhere in-between /// (a modified piecewise hermite function that squishes the function @@ -76,51 +68,77 @@ enum struct ColorSpace /// will default to to Midpoint = 0.5 (halfway between the control points) and /// Sharpness = 0.0 (linear). /// -/// ColorTable also contains which ColorSpace should be used for interpolation +/// ColorTable also contains which ColorSpace should be used for interpolation. +/// The color space is selected with the `vtkm::ColorSpace` enumeration. /// Currently the valid ColorSpaces are: -/// - RGB -/// - HSV -/// - HSV_WRAP -/// - LAB -/// - Diverging +/// - `RGB` +/// - `HSV` +/// - `HSVWrap` +/// - `Lab` +/// - `Diverging` /// -/// In HSV_WRAP mode, it will take the shortest path +/// In `HSVWrap` mode, it will take the shortest path /// in Hue (going back through 0 if that is the shortest way around the hue -/// circle) whereas HSV will not go through 0 (in order the -/// match the current functionality of vtkLookupTable). In Lab mode, +/// circle) whereas HSV will not go through 0 (in order to +/// match the current functionality of `vtkLookupTable`). In `Lab` mode, /// it will take the shortest path in the Lab color space with respect to the -/// CIE Delta E 2000 color distance measure. Diverging is a special +/// CIE Delta E 2000 color distance measure. `Diverging` is a special /// mode where colors will pass through white when interpolating between two /// saturated colors. /// -/// To map a field from a vtkm::cont::DataSet through the color and opacity transfer -/// functions and into a RGB or RGBA array you should use vtkm::filter::FieldToColor. +/// To map a field from a `vtkm::cont::DataSet` through the color and opacity transfer +/// functions and into a RGB or RGBA array you should use `vtkm::filter::FieldToColor`. /// -class VTKM_CONT_EXPORT ColorTable +/// Note that modifications of `vtkm::cont::ColorTable` are not thread safe. You should +/// not modify a `ColorTable` simultaneously in 2 or more threads. Also, you should not +/// modify a `ColorTable` that might be used in the execution environment. However, +/// the `ColorTable` can be used in multiple threads and on multiple devices as long +/// as no modifications are made. +/// +class VTKM_CONT_EXPORT ColorTable : public vtkm::cont::ExecutionObjectBase { - std::shared_ptr Impl; + std::shared_ptr Internals; public: enum struct Preset { - DEFAULT, - COOL_TO_WARM, - COOL_TO_WARM_EXTENDED, - VIRIDIS, - INFERNO, - PLASMA, - BLACK_BODY_RADIATION, - X_RAY, - GREEN, - BLACK_BLUE_WHITE, - BLUE_TO_ORANGE, - GRAY_TO_RED, - COLD_AND_HOT, - BLUE_GREEN_ORANGE, - YELLOW_GRAY_BLUE, - RAINBOW_UNIFORM, - JET, - RAINBOW_DESATURATED + Default, + CoolToWarm, + CoolToWarmExtended, + Viridis, + Inferno, + Plasma, + BlackBodyRadiation, + XRay, + Green, + BlackBlueWhite, + BlueToOrange, + GrayToRed, + ColdAndHot, + BlueGreenOrange, + YellowGrayBlue, + RainbowUniform, + Jet, + RainbowDesaturated, + + DEFAULT VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Default."), + COOL_TO_WARM VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::CoolToWarm."), + COOL_TO_WARM_EXTENDED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::CoolToWarmExtended."), + VIRIDIS VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Viridis."), + INFERNO VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Inferno."), + PLASMA VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Plasma."), + BLACK_BODY_RADIATION VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlackBodyRadiation."), + X_RAY VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::XRay."), + GREEN VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Green."), + BLACK_BLUE_WHITE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlackBlueWhite."), + BLUE_TO_ORANGE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlueToOrange."), + GRAY_TO_RED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::GrayToRed."), + COLD_AND_HOT VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::ColdAndHot."), + BLUE_GREEN_ORANGE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlueGreenOrange."), + YELLOW_GRAY_BLUE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::YellowGrayBlue."), + RAINBOW_UNIFORM VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::RainbowUniform."), + JET VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Jet."), + RAINBOW_DESATURATED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::RainbowDesaturated.") }; /// \brief Construct a color table from a preset @@ -130,7 +148,7 @@ public: /// /// Note: these are a select set of the presets you can get by providing a string identifier. /// - ColorTable(vtkm::cont::ColorTable::Preset preset = vtkm::cont::ColorTable::Preset::DEFAULT); + ColorTable(vtkm::cont::ColorTable::Preset preset = vtkm::cont::ColorTable::Preset::Default); /// \brief Construct a color table from a preset color table /// @@ -165,41 +183,42 @@ public: /// /// Note: The color table will have 0 entries /// Note: The alpha table will have 0 entries - explicit ColorTable(ColorSpace space); + explicit ColorTable(vtkm::ColorSpace space); /// Construct a color table with a 2 positions /// /// Note: The color table will have 2 entries of rgb = {1.0,1.0,1.0} /// Note: The alpha table will have 2 entries of alpha = 1.0 with linear /// interpolation - ColorTable(const vtkm::Range& range, ColorSpace space = ColorSpace::LAB); + ColorTable(const vtkm::Range& range, vtkm::ColorSpace space = vtkm::ColorSpace::Lab); /// Construct a color table with 2 positions // /// Note: The alpha table will have 2 entries of alpha = 1.0 with linear /// interpolation ColorTable(const vtkm::Range& range, - const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - ColorSpace space = ColorSpace::LAB); + const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::ColorSpace space = vtkm::ColorSpace::Lab); /// Construct color and alpha and table with 2 positions /// /// Note: The alpha table will use linear interpolation ColorTable(const vtkm::Range& range, - const vtkm::Vec& rgba1, - const vtkm::Vec& rgba2, - ColorSpace space = ColorSpace::LAB); + const vtkm::Vec4f_32& rgba1, + const vtkm::Vec4f_32& rgba2, + vtkm::ColorSpace space = vtkm::ColorSpace::Lab); /// Construct a color table with a list of colors and alphas. For this version you must also /// specify a name. /// /// This constructor is mostly used for presets. - ColorTable(const std::string& name, - vtkm::cont::ColorSpace colorSpace, - const vtkm::Vec& nanColor, - const std::vector& rgbPoints, - const std::vector& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 }); + ColorTable( + const std::string& name, + vtkm::ColorSpace colorSpace, + const vtkm::Vec3f_64& nanColor, + const std::vector& rgbPoints, + const std::vector& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 }); ~ColorTable(); @@ -257,8 +276,8 @@ public: ColorTable MakeDeepCopy(); /// - ColorSpace GetColorSpace() const; - void SetColorSpace(ColorSpace space); + vtkm::ColorSpace GetColorSpace() const; + void SetColorSpace(vtkm::ColorSpace space); /// If clamping is disabled values that lay out side /// the color table range are colored based on Below @@ -274,19 +293,19 @@ public: /// that is below the given range /// /// Default value is {0,0,0} - void SetBelowRangeColor(const vtkm::Vec& c); - const vtkm::Vec& GetBelowRangeColor() const; + void SetBelowRangeColor(const vtkm::Vec3f_32& c); + const vtkm::Vec3f_32& GetBelowRangeColor() const; /// Color to use when clamping is disabled for any value /// that is above the given range /// /// Default value is {0,0,0} - void SetAboveRangeColor(const vtkm::Vec& c); - const vtkm::Vec& GetAboveRangeColor() const; + void SetAboveRangeColor(const vtkm::Vec3f_32& c); + const vtkm::Vec3f_32& GetAboveRangeColor() const; /// - void SetNaNColor(const vtkm::Vec& c); - const vtkm::Vec& GetNaNColor() const; + void SetNaNColor(const vtkm::Vec3f_32& c); + const vtkm::Vec3f_32& GetNaNColor() const; /// Remove all existing values in both color and alpha tables. /// Does not remove the clamping, below, and above range state or colors. @@ -321,40 +340,40 @@ public: /// /// Note: rgb values need to be between 0 and 1.0 (inclusive). /// Return the index of the point (0 based), or -1 osn error. - vtkm::Int32 AddPoint(double x, const vtkm::Vec& rgb); + vtkm::Int32 AddPoint(vtkm::Float64 x, const vtkm::Vec3f_32& rgb); /// Adds a point to the color function. If the point already exists, it /// will be updated to the new value. /// /// Note: hsv values need to be between 0 and 1.0 (inclusive). /// Return the index of the point (0 based), or -1 on error. - vtkm::Int32 AddPointHSV(double x, const vtkm::Vec& hsv); + vtkm::Int32 AddPointHSV(vtkm::Float64 x, const vtkm::Vec3f_32& hsv); /// Add a line segment to the color function. All points which lay between x1 and x2 /// (inclusive) are removed from the function. /// /// Note: rgb1, and rgb2 values need to be between 0 and 1.0 (inclusive). /// Return the index of the point x1 (0 based), or -1 on error. - vtkm::Int32 AddSegment(double x1, - const vtkm::Vec& rgb1, - double x2, - const vtkm::Vec& rgb2); + vtkm::Int32 AddSegment(vtkm::Float64 x1, + const vtkm::Vec3f_32& rgb1, + vtkm::Float64 x2, + const vtkm::Vec3f_32& rgb2); /// Add a line segment to the color function. All points which lay between x1 and x2 /// (inclusive) are removed from the function. /// /// Note: hsv1, and hsv2 values need to be between 0 and 1.0 (inclusive) /// Return the index of the point x1 (0 based), or -1 on error - vtkm::Int32 AddSegmentHSV(double x1, - const vtkm::Vec& hsv1, - double x2, - const vtkm::Vec& hsv2); + vtkm::Int32 AddSegmentHSV(vtkm::Float64 x1, + const vtkm::Vec3f_32& hsv1, + vtkm::Float64 x2, + const vtkm::Vec3f_32& hsv2); /// Get the location, and rgb information for an existing point in the opacity function. /// /// Note: components 1-3 are rgb and will have values between 0 and 1.0 (inclusive) /// Return the index of the point (0 based), or -1 on error. - bool GetPoint(vtkm::Int32 index, vtkm::Vec&) const; + bool GetPoint(vtkm::Int32 index, vtkm::Vec4f_64&) const; /// Update the location, and rgb information for an existing point in the color function. /// If the location value for the index is modified the point is removed from @@ -362,12 +381,12 @@ public: /// /// Note: components 1-3 are rgb and must have values between 0 and 1.0 (inclusive). /// Return the new index of the updated point (0 based), or -1 on error. - vtkm::Int32 UpdatePoint(vtkm::Int32 index, const vtkm::Vec&); + vtkm::Int32 UpdatePoint(vtkm::Int32 index, const vtkm::Vec4f_64&); /// Remove the Color function point that exists at exactly x /// /// Return true if the point x exists and has been removed - bool RemovePoint(double x); + bool RemovePoint(vtkm::Float64 x); /// Remove the Color function point n /// @@ -385,14 +404,20 @@ public: /// /// Note: alpha needs to be a value between 0 and 1.0 (inclusive). /// Return the index of the point (0 based), or -1 on error. - vtkm::Int32 AddPointAlpha(double x, float alpha) { return AddPointAlpha(x, alpha, 0.5f, 0.0f); } + vtkm::Int32 AddPointAlpha(vtkm::Float64 x, vtkm::Float32 alpha) + { + return AddPointAlpha(x, alpha, 0.5f, 0.0f); + } /// Adds a point to the opacity function. If the point already exists, it /// will be updated to the new value. /// /// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive) /// Return the index of the point (0 based), or -1 on error. - vtkm::Int32 AddPointAlpha(double x, float alpha, float midpoint, float sharpness); + vtkm::Int32 AddPointAlpha(vtkm::Float64 x, + vtkm::Float32 alpha, + vtkm::Float32 midpoint, + vtkm::Float32 sharpness); /// Add a line segment to the opacity function. All points which lay between x1 and x2 /// (inclusive) are removed from the function. Uses a midpoint of @@ -400,9 +425,12 @@ public: /// /// Note: alpha values need to be between 0 and 1.0 (inclusive) /// Return the index of the point x1 (0 based), or -1 on error - vtkm::Int32 AddSegmentAlpha(double x1, float alpha1, double x2, float alpha2) + vtkm::Int32 AddSegmentAlpha(vtkm::Float64 x1, + vtkm::Float32 alpha1, + vtkm::Float64 x2, + vtkm::Float32 alpha2) { - vtkm::Vec mid_sharp(0.5f, 0.0f); + vtkm::Vec2f_32 mid_sharp(0.5f, 0.0f); return AddSegmentAlpha(x1, alpha1, x2, alpha2, mid_sharp, mid_sharp); } @@ -411,19 +439,19 @@ public: /// /// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive) /// Return the index of the point x1 (0 based), or -1 on error - vtkm::Int32 AddSegmentAlpha(double x1, - float alpha1, - double x2, - float alpha2, - const vtkm::Vec& mid_sharp1, - const vtkm::Vec& mid_sharp2); + vtkm::Int32 AddSegmentAlpha(vtkm::Float64 x1, + vtkm::Float32 alpha1, + vtkm::Float64 x2, + vtkm::Float32 alpha2, + const vtkm::Vec2f_32& mid_sharp1, + const vtkm::Vec2f_32& mid_sharp2); /// Get the location, alpha, midpoint and sharpness information for an existing /// point in the opacity function. /// /// Note: alpha, midpoint, and sharpness values all will be between 0 and 1.0 (inclusive) /// Return the index of the point (0 based), or -1 on error. - bool GetPointAlpha(vtkm::Int32 index, vtkm::Vec&) const; + bool GetPointAlpha(vtkm::Int32 index, vtkm::Vec4f_64&) const; /// Update the location, alpha, midpoint and sharpness information for an existing /// point in the opacity function. @@ -432,12 +460,12 @@ public: /// /// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive) /// Return the new index of the updated point (0 based), or -1 on error. - vtkm::Int32 UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec&); + vtkm::Int32 UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec4f_64&); /// Remove the Opacity function point that exists at exactly x /// /// Return true if the point x exists and has been removed - bool RemovePointAlpha(double x); + bool RemovePointAlpha(vtkm::Float64 x); /// Remove the Opacity function point n /// @@ -447,9 +475,9 @@ public: /// Returns the number of points in the alpha function vtkm::Int32 GetNumberOfPointsAlpha() const; - /// Fill the Color table from a double pointer + /// Fill the Color table from a vtkm::Float64 pointer /// - /// The double pointer is required to have the layout out of [X1, R1, + /// The vtkm::Float64 pointer is required to have the layout out of [X1, R1, /// G1, B1, X2, R2, G2, B2, ..., Xn, Rn, Gn, Bn] where n is the /// number of nodes. /// This will remove any existing color control points. @@ -458,11 +486,11 @@ public: /// /// Note: This is provided as a interoperability method with VTK /// Will return false and not modify anything if n is <= 0 or ptr == nullptr - bool FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr); + bool FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr); - /// Fill the Color table from a float pointer + /// Fill the Color table from a vtkm::Float32 pointer /// - /// The double pointer is required to have the layout out of [X1, R1, + /// The vtkm::Float64 pointer is required to have the layout out of [X1, R1, /// G1, B1, X2, R2, G2, B2, ..., Xn, Rn, Gn, Bn] where n is the /// number of nodes. /// This will remove any existing color control points. @@ -471,11 +499,11 @@ public: /// /// Note: This is provided as a interoperability method with VTK /// Will return false and not modify anything if n is <= 0 or ptr == nullptr - bool FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr); + bool FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr); - /// Fill the Opacity table from a double pointer + /// Fill the Opacity table from a vtkm::Float64 pointer /// - /// The double pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2, + /// The vtkm::Float64 pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2, /// ..., Xn, An, Mn, Sn] where n is the number of nodes. The Xi values represent the value to /// map, the Ai values represent alpha (opacity) value, the Mi values represent midpoints, and /// the Si values represent sharpness. Use 0.5 for midpoint and 0.0 for sharpness to have linear @@ -486,11 +514,11 @@ public: /// Note: n represents the length of the array, so ( n/4 == number of control points ) /// /// Will return false and not modify anything if n is <= 0 or ptr == nullptr - bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* ptr); + bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr); - /// Fill the Opacity table from a float pointer + /// Fill the Opacity table from a vtkm::Float32 pointer /// - /// The float pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2, + /// The vtkm::Float32 pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2, /// ..., Xn, An, Mn, Sn] where n is the number of nodes. The Xi values represent the value to /// map, the Ai values represent alpha (opacity) value, the Mi values represent midpoints, and /// the Si values represent sharpness. Use 0.5 for midpoint and 0.0 for sharpness to have linear @@ -501,7 +529,7 @@ public: /// Note: n represents the length of the array, so ( n/4 == number of control points ) /// /// Will return false and not modify anything if n is <= 0 or ptr == nullptr - bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr); + bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr); /// \brief Sample each value through an intermediate lookup/sample table to generate RGBA colors @@ -628,8 +656,8 @@ public: /// /// Will use the current range of the color table to generate evenly spaced /// values using either vtkm::Float32 or vtkm::Float64 space. - /// Will use vtkm::Float32 space when the difference between the float and double - /// values when the range is within float space and the following are within a tolerance: + /// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64 + /// values when the range is within vtkm::Float32 space and the following are within a tolerance: /// /// - (max-min) / numSamples /// - ((max-min) / numSamples) * numSamples @@ -637,14 +665,14 @@ public: /// Note: This will return false if the number of samples is less than 2 inline bool Sample(vtkm::Int32 numSamples, vtkm::cont::ColorTableSamplesRGBA& samples, - double tolerance = 0.002) const; + vtkm::Float64 tolerance = 0.002) const; /// \brief generate a sample lookup table using regular spaced samples along the range. /// /// Will use the current range of the color table to generate evenly spaced /// values using either vtkm::Float32 or vtkm::Float64 space. - /// Will use vtkm::Float32 space when the difference between the float and double - /// values when the range is within float space and the following are within a tolerance: + /// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64 + /// values when the range is within vtkm::Float32 space and the following are within a tolerance: /// /// - (max-min) / numSamples /// - ((max-min) / numSamples) * numSamples @@ -652,14 +680,14 @@ public: /// Note: This will return false if the number of samples is less than 2 inline bool Sample(vtkm::Int32 numSamples, vtkm::cont::ColorTableSamplesRGB& samples, - double tolerance = 0.002) const; + vtkm::Float64 tolerance = 0.002) const; /// \brief generate RGBA colors using regular spaced samples along the range. /// /// Will use the current range of the color table to generate evenly spaced /// values using either vtkm::Float32 or vtkm::Float64 space. - /// Will use vtkm::Float32 space when the difference between the float and double - /// values when the range is within float space and the following are within a tolerance: + /// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64 + /// values when the range is within vtkm::Float32 space and the following are within a tolerance: /// /// - (max-min) / numSamples /// - ((max-min) / numSamples) * numSamples @@ -667,14 +695,14 @@ public: /// Note: This will return false if the number of samples is less than 2 inline bool Sample(vtkm::Int32 numSamples, vtkm::cont::ArrayHandle& colors, - double tolerance = 0.002) const; + vtkm::Float64 tolerance = 0.002) const; /// \brief generate RGB colors using regular spaced samples along the range. /// /// Will use the current range of the color table to generate evenly spaced /// values using either vtkm::Float32 or vtkm::Float64 space. - /// Will use vtkm::Float32 space when the difference between the float and double - /// values when the range is within float space and the following are within a tolerance: + /// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64 + /// values when the range is within vtkm::Float32 space and the following are within a tolerance: /// /// - (max-min) / numSamples /// - ((max-min) / numSamples) * numSamples @@ -682,48 +710,30 @@ public: /// Note: This will return false if the number of samples is less than 2 inline bool Sample(vtkm::Int32 numSamples, vtkm::cont::ArrayHandle& colors, - double tolerance = 0.002) const; + vtkm::Float64 tolerance = 0.002) const; /// \brief returns a virtual object pointer of the exec color table /// /// This pointer is only valid as long as the ColorTable is unmodified - inline const vtkm::exec::ColorTableBase* PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId, - vtkm::cont::Token& token) const; + vtkm::exec::ColorTable PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId, + vtkm::cont::Token& token) const; VTKM_DEPRECATED(1.6, "PrepareForExecution now requires a vtkm::cont::Token object") - inline const vtkm::exec::ColorTableBase* PrepareForExecution( - vtkm::cont::DeviceAdapterId deviceId) const; + inline vtkm::exec::ColorTable PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId) const; - /// \brief returns the modified count for the virtual object handle of the exec color table + /// \brief Returns the modified count for changes of the color table /// + /// The `ModifiedCount` of the color table starts at 1 and gets incremented + /// every time a change is made to the color table. /// The modified count allows consumers of a shared color table to keep track /// if the color table has been modified since the last time they used it. + /// This is important for consumers that need to sample the color table. + /// You only want to resample the color table if changes have been made. vtkm::Id GetModifiedCount() const; - struct TransferState - { - bool NeedsTransfer; - vtkm::exec::ColorTableBase* Portal; - const vtkm::cont::ArrayHandle& ColorPosHandle; - const vtkm::cont::ArrayHandle>& ColorRGBHandle; - const vtkm::cont::ArrayHandle& OpacityPosHandle; - const vtkm::cont::ArrayHandle& OpacityAlphaHandle; - const vtkm::cont::ArrayHandle>& OpacityMidSharpHandle; - }; - private: - bool NeedToCreateExecutionColorTable() const; - - //takes ownership of the pointer passed in - void UpdateExecutionColorTable( - vtkm::cont::VirtualObjectHandle*) const; - - ColorTable::TransferState GetExecutionDataForTransfer() const; - - vtkm::exec::ColorTableBase* GetControlRepresentation() const; - - vtkm::cont::VirtualObjectHandle const* GetExecutionHandle() const; + void UpdateArrayHandles() const; }; } } //namespace vtkm::cont diff --git a/vtkm/cont/ColorTable.hxx b/vtkm/cont/ColorTable.hxx index 3d7790740..9a2b64db9 100644 --- a/vtkm/cont/ColorTable.hxx +++ b/vtkm/cont/ColorTable.hxx @@ -29,52 +29,6 @@ namespace cont namespace detail { -template -inline T* get_ptr(T* t) -{ - return t; -} -#if defined(VTKM_MSVC) -//ArrayPortalToIteratorBegin could be returning a checked_array_iterator so -//we need to grab the underlying pointer -template -inline T* get_ptr(stdext::checked_array_iterator t) -{ - return t.base(); -} -#endif - -struct transfer_color_table_to_device -{ - - template - inline bool operator()(DeviceAdapter device, - vtkm::cont::ColorTable::TransferState&& state, - vtkm::cont::Token& token) const - { - auto p1 = state.ColorPosHandle.PrepareForInput(device, token); - auto p2 = state.ColorRGBHandle.PrepareForInput(device, token); - auto p3 = state.OpacityPosHandle.PrepareForInput(device, token); - auto p4 = state.OpacityAlphaHandle.PrepareForInput(device, token); - auto p5 = state.OpacityMidSharpHandle.PrepareForInput(device, token); - - //The rest of the data member on portal are set when-ever the user - //modifies the ColorTable instance and don't need to specified here - - state.Portal->ColorSize = static_cast(state.ColorPosHandle.GetNumberOfValues()); - state.Portal->OpacitySize = - static_cast(state.OpacityPosHandle.GetNumberOfValues()); - - state.Portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1)); - state.Portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2)); - state.Portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3)); - state.Portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4)); - state.Portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5)); - state.Portal->Modified(); - return true; - } -}; - struct map_color_table { template @@ -349,77 +303,6 @@ bool ColorTable::Sample(vtkm::Int32 numSamples, } return sampleColorTable(this, numSamples, colors, tolerance, false); } - -//--------------------------------------------------------------------------- -const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution( - vtkm::cont::DeviceAdapterId device, - vtkm::cont::Token& token) const -{ - //Build the ColorTable instance that is needed for execution - if (this->NeedToCreateExecutionColorTable()) - { - auto space = this->GetColorSpace(); - auto hostPortal = this->GetControlRepresentation(); - //Remove any existing host and execution data. The allocation of the - //virtual object handle needs to occur in the .hxx so that it happens - //in the same library as the user and will be a valid virtual object - using HandleType = vtkm::cont::VirtualObjectHandle; - switch (space) - { - case vtkm::cont::ColorSpace::RGB: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::HSV: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::HSV_WRAP: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::LAB: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - case vtkm::cont::ColorSpace::DIVERGING: - { - this->UpdateExecutionColorTable( - new HandleType(static_cast(hostPortal), false)); - break; - } - } - } - - - //transfer ColorTable and all related data - auto&& info = this->GetExecutionDataForTransfer(); - if (info.NeedsTransfer) - { - bool transfered = vtkm::cont::TryExecuteOnDevice( - device, detail::transfer_color_table_to_device{}, std::move(info), token); - if (!transfered) - { - throwFailedRuntimeDeviceTransfer("ColorTable", device); - } - } - return this->GetExecutionHandle()->PrepareForExecution(device, token); -} - -const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution( - vtkm::cont::DeviceAdapterId device) const -{ - vtkm::cont::Token token; - return this->PrepareForExecution(device, token); -} } } #endif diff --git a/vtkm/cont/ColorTablePresets.cxx b/vtkm/cont/ColorTablePresets.cxx index 84d384dc2..17096502f 100644 --- a/vtkm/cont/ColorTablePresets.cxx +++ b/vtkm/cont/ColorTablePresets.cxx @@ -24,28 +24,28 @@ namespace cont namespace internal { -static vtkm::cont::ColorTable::Preset DEFAULT_PRESET = vtkm::cont::ColorTable::Preset::VIRIDIS; +static vtkm::cont::ColorTable::Preset DEFAULT_PRESET = vtkm::cont::ColorTable::Preset::Viridis; -std::string GetColorSpaceString(vtkm::cont::ColorSpace space) +std::string GetColorSpaceString(vtkm::ColorSpace space) { switch (space) { - case vtkm::cont::ColorSpace::RGB: + case vtkm::ColorSpace::RGB: return std::string("RGB"); - case vtkm::cont::ColorSpace::HSV: + case vtkm::ColorSpace::HSV: return std::string("HSV"); - case vtkm::cont::ColorSpace::HSV_WRAP: - return std::string("HSV_WRAP"); - case vtkm::cont::ColorSpace::LAB: + case vtkm::ColorSpace::HSVWrap: + return std::string("HSVWrap"); + case vtkm::ColorSpace::Lab: return std::string("Lab"); - case vtkm::cont::ColorSpace::DIVERGING: + case vtkm::ColorSpace::Diverging: return std::string("Diverging"); } throw vtkm::cont::ErrorBadValue("Encountered invalid color space."); } -vtkm::cont::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString) +vtkm::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString) { std::string spaceString = colorSpaceString; @@ -56,27 +56,27 @@ vtkm::cont::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString) if (spaceString == "rgb") { - return vtkm::cont::ColorSpace::RGB; + return vtkm::ColorSpace::RGB; } if (spaceString == "hsv") { - return vtkm::cont::ColorSpace::HSV; + return vtkm::ColorSpace::HSV; } if ((spaceString == "hsv_wrap") || (spaceString == "hsv-wrap") || (spaceString == "hsvwrap")) { - return vtkm::cont::ColorSpace::HSV_WRAP; + return vtkm::ColorSpace::HSVWrap; } if (spaceString == "lab") { - return vtkm::cont::ColorSpace::LAB; + return vtkm::ColorSpace::Lab; } if (spaceString == "diverging") { - return vtkm::cont::ColorSpace::DIVERGING; + return vtkm::ColorSpace::Diverging; } std::stringstream message; @@ -116,7 +116,7 @@ struct ColorTablePreset { vtkm::cont::ColorTable::Preset Preset; std::string Name; - vtkm::cont::ColorSpace ColorSpace; + vtkm::ColorSpace ColorSpace; vtkm::Vec NanColor; std::vector RGBPoints; std::vector AlphaPoints; @@ -124,13 +124,13 @@ struct ColorTablePreset VTKM_CONT ColorTablePreset(vtkm::cont::ColorTable::Preset preset, std::string&& name, - vtkm::cont::ColorSpace colorSpace, + vtkm::ColorSpace colorSpace, vtkm::Vec&& nanColor, std::vector&& rgbPoints, std::vector&& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 }) : Preset(preset) , Name(std::move(name)) - , ColorSpace(std::move(colorSpace)) + , ColorSpace(colorSpace) , NanColor(std::move(nanColor)) , RGBPoints(std::move(rgbPoints)) , AlphaPoints(std::move(alphaPoints)) @@ -148,9 +148,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese { // clang-format off presets = std::vector{ - { vtkm::cont::ColorTable::Preset::COOL_TO_WARM, + { vtkm::cont::ColorTable::Preset::CoolToWarm, "Cool to Warm", - vtkm::cont::ColorSpace::DIVERGING, + vtkm::ColorSpace::Diverging, { 1, 1, 0 }, { 0, 0.23137254902, 0.298039215686, 0.752941176471, @@ -158,9 +158,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1, 0.705882352941, 0.0156862745098, 0.149019607843 } }, - { vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED, + { vtkm::cont::ColorTable::Preset::CoolToWarmExtended, "Cool to Warm Extended", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0.25, 0, 0 }, { 0, 0, 0, 0.34902, @@ -200,9 +200,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1, 0.34902, 0.070588, 0.211765 } }, - { vtkm::cont::ColorTable::Preset::VIRIDIS, + { vtkm::cont::ColorTable::Preset::Viridis, "Viridis", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 1, 0, 0 }, { 0.000000, 0.282365, 0.000000, 0.331010, @@ -463,9 +463,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.000000, 0.952999, 0.912545, 0.110859 } }, - { vtkm::cont::ColorTable::Preset::INFERNO, + { vtkm::cont::ColorTable::Preset::Inferno, "Inferno", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0, 1, 0 }, { 0.000000, 0.002811, 0.000240, 0.013985, @@ -726,9 +726,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.000000, 0.959400, 1.002963, 0.640626 } }, - { vtkm::cont::ColorTable::Preset::PLASMA, + { vtkm::cont::ColorTable::Preset::Plasma, "Plasma", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0, 1, 0 }, { 0.000000, 0.185001, 0.000000, 0.530073, @@ -989,9 +989,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.000000, 0.894058, 0.982254, 0.081069 } }, - { vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION, + { vtkm::cont::ColorTable::Preset::BlackBodyRadiation, "Black-Body Radiation", - vtkm::cont::ColorSpace::RGB, + vtkm::ColorSpace::RGB, { 0, 0.498039215686, 1 }, { 0, 0, 0, 0, @@ -1000,15 +1000,15 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1, 1, 1, 1 } }, - { vtkm::cont::ColorTable::Preset::X_RAY, + { vtkm::cont::ColorTable::Preset::XRay, "X Ray", - vtkm::cont::ColorSpace::RGB, + vtkm::ColorSpace::RGB, { 1, 0, 0 }, { 0, 1, 1, 1, 1, 0, 0, 0 } }, - { vtkm::cont::ColorTable::Preset::GREEN, + { vtkm::cont::ColorTable::Preset::Green, "Green", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0.25, 0, 0 }, { 0.00, 0.054902, 0.109804, 0.121569, @@ -1034,9 +1034,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.00, 1.000000, 0.984314, 0.901961 } }, - { vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE, + { vtkm::cont::ColorTable::Preset::BlackBlueWhite, "Black - Blue - White", - vtkm::cont::ColorSpace::RGB, + vtkm::ColorSpace::RGB, { 1, 1, 0 }, { 0, 0, 0, 0, @@ -1045,9 +1045,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1, 1, 1, 1 } }, - { vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE, + { vtkm::cont::ColorTable::Preset::BlueToOrange, "Blue to Orange", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0.25, 0, 0 }, { 0.000000, 0.086275, 0.003922, 0.298039, @@ -1098,9 +1098,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.000000, 0.188235, 0.000000, 0.070588 } }, - {vtkm::cont::ColorTable::Preset::GRAY_TO_RED, + {vtkm::cont::ColorTable::Preset::GrayToRed, "Gray to Red", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0, 0.498039215686, 1 }, { 0.000000, 0.101961, 0.101961, 0.101961, @@ -1122,9 +1122,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.000000, 0.403922, 0.000000, 0.121569 } }, - { vtkm::cont::ColorTable::Preset::COLD_AND_HOT, + { vtkm::cont::ColorTable::Preset::ColdAndHot, "Cold and Hot", - vtkm::cont::ColorSpace::RGB, + vtkm::ColorSpace::RGB, { 1, 1, 0 }, { 0, 0, 1, 1, @@ -1134,9 +1134,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1, 1, 1, 0 } }, - { vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE, + { vtkm::cont::ColorTable::Preset::BlueGreenOrange, "Blue - Green - Orange", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0.25, 0.0, 0.0 }, { 0.0,0.831373,0.909804,0.980392, @@ -1191,9 +1191,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.0,0.45098,0.007843,0.0 } }, - { vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE, + { vtkm::cont::ColorTable::Preset::YellowGrayBlue, "Yellow - Gray - Blue", - vtkm::cont::ColorSpace::LAB, + vtkm::ColorSpace::Lab, { 0.25, 0, 0 }, { 0.000000, 0.301961, 0.047059, 0.090196, @@ -1253,9 +1253,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.000000, 0.890196, 0.956863, 0.984314 } }, - { vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM, + { vtkm::cont::ColorTable::Preset::RainbowUniform, "Rainbow Uniform", - vtkm::cont::ColorSpace::RGB, + vtkm::ColorSpace::RGB, { 1, 0, 0 }, { 0.000000,0.020000,0.381300,0.998100, @@ -1303,9 +1303,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1.000000,0.683700,0.050000,0.413900 } }, - { vtkm::cont::ColorTable::Preset::JET, + { vtkm::cont::ColorTable::Preset::Jet, "Jet", - vtkm::cont::ColorSpace::RGB, + vtkm::ColorSpace::RGB, { 0.25, 0, 0 }, { 0, 0, 0, 0.5625, @@ -1317,9 +1317,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector& prese 1, 0.5, 0, 0 } }, - { vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED, + { vtkm::cont::ColorTable::Preset::RainbowDesaturated, "Rainbow Desaturated", - vtkm::cont::ColorSpace::RGB, + vtkm::ColorSpace::RGB, { 1, 1, 0 }, { 0, 0.278431372549, 0.278431372549, 0.858823529412, @@ -1357,7 +1357,7 @@ namespace internal VTKM_CONT_EXPORT bool LoadColorTablePreset(vtkm::cont::ColorTable::Preset preset, vtkm::cont::ColorTable& table) { - if (preset == vtkm::cont::ColorTable::Preset::DEFAULT) + if (preset == vtkm::cont::ColorTable::Preset::Default) { preset = DEFAULT_PRESET; } @@ -1369,7 +1369,52 @@ bool LoadColorTablePreset(vtkm::cont::ColorTable::Preset preset, vtkm::cont::Col return true; } } - return false; + + VTKM_DEPRECATED_SUPPRESS_BEGIN + // Handle deprecated names + switch (preset) + { + case vtkm::cont::ColorTable::Preset::DEFAULT: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Default, table); + case vtkm::cont::ColorTable::Preset::COOL_TO_WARM: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::CoolToWarm, table); + case vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::CoolToWarmExtended, table); + case vtkm::cont::ColorTable::Preset::VIRIDIS: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Viridis, table); + case vtkm::cont::ColorTable::Preset::INFERNO: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Inferno, table); + case vtkm::cont::ColorTable::Preset::PLASMA: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Plasma, table); + case vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlackBodyRadiation, table); + case vtkm::cont::ColorTable::Preset::X_RAY: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::XRay, table); + case vtkm::cont::ColorTable::Preset::GREEN: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Green, table); + case vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlackBlueWhite, table); + case vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlueToOrange, table); + case vtkm::cont::ColorTable::Preset::GRAY_TO_RED: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::GrayToRed, table); + case vtkm::cont::ColorTable::Preset::COLD_AND_HOT: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::ColdAndHot, table); + case vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlueGreenOrange, table); + case vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::YellowGrayBlue, table); + case vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::RainbowUniform, table); + case vtkm::cont::ColorTable::Preset::JET: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Jet, table); + case vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED: + return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::RainbowDesaturated, table); + default: + // Should not get here. + return false; + } + VTKM_DEPRECATED_SUPPRESS_END } VTKM_CONT_EXPORT std::set GetPresetNames() diff --git a/vtkm/cont/ColorTablePrivate.hxx b/vtkm/cont/ColorTablePrivate.hxx deleted file mode 100644 index 7f3e2bd9d..000000000 --- a/vtkm/cont/ColorTablePrivate.hxx +++ /dev/null @@ -1,295 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ -#include -#include - -#include -#include - -#include -#include - -namespace vtkm -{ -namespace cont -{ - -namespace detail -{ -struct ColorTableInternals -{ - std::string Name; - - ColorSpace CSpace = ColorSpace::LAB; - vtkm::Range TableRange = { 1.0, 0.0 }; - - //Host side version of the ColorTableBase. This holds data such as: - // NanColor - // BelowRangeColor - // AboveRangeColor - // UseClamping - // BelowRangeColor - // AboveRangeColor - //Note the pointers inside the host side portal are not valid, as they - //are execution pointers - std::unique_ptr HostSideCache; - //Execution side version of the ColorTableBase. - std::unique_ptr> ExecHandle; - - std::vector ColorNodePos; - std::vector> ColorRGB; - - std::vector OpacityNodePos; - std::vector OpacityAlpha; - std::vector> OpacityMidSharp; - - vtkm::cont::ArrayHandle ColorPosHandle; - vtkm::cont::ArrayHandle> ColorRGBHandle; - vtkm::cont::ArrayHandle OpacityPosHandle; - vtkm::cont::ArrayHandle OpacityAlphaHandle; - vtkm::cont::ArrayHandle> OpacityMidSharpHandle; - bool ColorArraysChanged = true; - bool OpacityArraysChanged = true; - bool HostSideCacheChanged = true; - - void RecalculateRange() - { - vtkm::Range r; - if (this->ColorNodePos.size() > 0) - { - r.Include(this->ColorNodePos.front()); - r.Include(this->ColorNodePos.back()); - } - - if (this->OpacityNodePos.size() > 0) - { - r.Include(this->OpacityNodePos.front()); - r.Include(this->OpacityNodePos.back()); - } - - this->TableRange = r; - } -}; -} //namespace detail - -namespace -{ - -template -struct MinDelta -{ -}; -// This value seems to work well for float ranges we have tested -template <> -struct MinDelta -{ - static constexpr int value = 2048; -}; -template <> -struct MinDelta -{ - static constexpr vtkm::Int64 value = 2048L; -}; - -// Reperesents the following: -// T m = std::numeric_limits::min(); -// EquivSizeIntT im; -// std::memcpy(&im, &m, sizeof(T)); -// -template -struct MinRepresentable -{ -}; -template <> -struct MinRepresentable -{ - static constexpr int value = 8388608; -}; -template <> -struct MinRepresentable -{ - static constexpr vtkm::Int64 value = 4503599627370496L; -}; - -inline bool rangeAlmostEqual(const vtkm::Range& r) -{ - vtkm::Int64 irange[2]; - // needs to be a memcpy to avoid strict aliasing issues, doing a count - // of 2*sizeof(T) to couple both values at the same time - std::memcpy(irange, &r.Min, sizeof(vtkm::Int64)); - std::memcpy(irange + 1, &r.Max, sizeof(vtkm::Int64)); - // determine the absolute delta between these two numbers. - const vtkm::Int64 delta = std::abs(irange[1] - irange[0]); - // If the numbers are not nearly equal, we don't touch them. This avoids running into - // pitfalls like BUG PV #17152. - return (delta < 1024) ? true : false; -} - -template -inline double expandRange(T r[2]) -{ - constexpr bool is_float32_type = std::is_same::value; - using IRange = typename std::conditional::type; - IRange irange[2]; - // needs to be a memcpy to avoid strict aliasing issues, doing a count - // of 2*sizeof(T) to couple both values at the same time - std::memcpy(irange, r, sizeof(T) * 2); - - const bool denormal = !std::isnormal(r[0]); - const IRange minInt = MinRepresentable::value; - const IRange minDelta = denormal ? minInt + MinDelta::value : MinDelta::value; - - // determine the absolute delta between these two numbers. - const vtkm::Int64 delta = std::abs(irange[1] - irange[0]); - - // if our delta is smaller than the min delta push out the max value - // so that it is equal to minRange + minDelta. When our range is entirely - // negative we should instead subtract from our max, to max a larger negative - // value - if (delta < minDelta) - { - if (irange[0] < 0) - { - irange[1] = irange[0] - minDelta; - } - else - { - irange[1] = irange[0] + minDelta; - } - - T result; - std::memcpy(&result, irange + 1, sizeof(T)); - return static_cast(result); - } - return static_cast(r[1]); -} - -inline vtkm::Range adjustRange(const vtkm::Range& r) -{ - const bool spans_zero_boundary = r.Min < 0 && r.Max > 0; - if (spans_zero_boundary) - { // nothing needs to be done, but this check is required. - // if we convert into integer space the delta difference will overflow - // an integer - return r; - } - if (rangeAlmostEqual(r)) - { - return r; - } - - // range should be left untouched as much as possible to - // to avoid loss of precision whenever possible. That is why - // we only modify the Max value - vtkm::Range result = r; - if (r.Min > static_cast(std::numeric_limits::lowest()) && - r.Max < static_cast(std::numeric_limits::max())) - { //We've found it best to offset it in float space if the numbers - //lay inside that representable range - float frange[2] = { static_cast(r.Min), static_cast(r.Max) }; - result.Max = expandRange(frange); - } - else - { - double drange[2] = { r.Min, r.Max }; - result.Max = expandRange(drange); - } - return result; -} - - -inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) -{ - vtkm::Vec rgb; - constexpr float onethird = 1.0f / 3.0f; - constexpr float onesixth = 1.0f / 6.0f; - constexpr float twothird = 2.0f / 3.0f; - constexpr float fivesixth = 5.0f / 6.0f; - - // compute RGB from HSV - if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red - { - rgb[1] = 1.0f; - rgb[0] = (onethird - hsv[0]) * 6.0f; - rgb[2] = 0.0f; - } - else if (hsv[0] > onethird && hsv[0] <= 0.5f) // green/blue - { - rgb[1] = 1.0f; - rgb[2] = (hsv[0] - onethird) * 6.0f; - rgb[0] = 0.0f; - } - else if (hsv[0] > 0.5 && hsv[0] <= twothird) // blue/green - { - rgb[2] = 1.0f; - rgb[1] = (twothird - hsv[0]) * 6.0f; - rgb[0] = 0.0f; - } - else if (hsv[0] > twothird && hsv[0] <= fivesixth) // blue/red - { - rgb[2] = 1.0f; - rgb[0] = (hsv[0] - twothird) * 6.0f; - rgb[1] = 0.0f; - } - else if (hsv[0] > fivesixth && hsv[0] <= 1.0) // red/blue - { - rgb[0] = 1.0f; - rgb[2] = (1.0f - hsv[0]) * 6.0f; - rgb[1] = 0.0f; - } - else // red/green - { - rgb[0] = 1.0f; - rgb[1] = hsv[0] * 6; - rgb[2] = 0.0f; - } - - // add Saturation to the equation. - rgb[0] = (hsv[1] * rgb[0] + (1.0f - hsv[1])); - rgb[1] = (hsv[1] * rgb[1] + (1.0f - hsv[1])); - rgb[2] = (hsv[1] * rgb[2] + (1.0f - hsv[1])); - - rgb[0] *= hsv[2]; - rgb[1] *= hsv[2]; - rgb[2] *= hsv[2]; - return rgb; -} - -// clang-format off -inline bool outside_vrange(double x) { return x < 0.0 || x > 1.0; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0 || x[2] < 0.0 || x[2] > 1.0; } -inline bool outside_vrange(float x) { return x < 0.0f || x > 1.0f; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f || x[2] < 0.0f || x[2] > 1.0f; } - -inline bool outside_range() { return false; } - -template -inline bool outside_range(T&& t) { return outside_vrange(t); } - -template -inline bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); } - -template -inline bool outside_range(T&& t, U&& u, V&& v, Args&&... args) -{ - return outside_vrange(t) || outside_vrange(u) || outside_vrange(v) || - outside_range(std::forward(args)...); -} -// clang-format on -} - -} //namespace cont -} //namespace vtkm diff --git a/vtkm/cont/testing/TestingColorTable.h b/vtkm/cont/testing/TestingColorTable.h index c4a2fb3f8..63f254718 100644 --- a/vtkm/cont/testing/TestingColorTable.h +++ b/vtkm/cont/testing/TestingColorTable.h @@ -59,9 +59,9 @@ public: vtkm::Range range{ 0.0, 1.0 }; vtkm::Vec rgb1{ 0.0f, 0.0f, 0.0f }; vtkm::Vec rgb2{ 1.0f, 1.0f, 1.0f }; - auto rgbspace = vtkm::cont::ColorSpace::RGB; - auto hsvspace = vtkm::cont::ColorSpace::HSV; - auto diverging = vtkm::cont::ColorSpace::DIVERGING; + auto rgbspace = vtkm::ColorSpace::RGB; + auto hsvspace = vtkm::ColorSpace::HSV; + auto diverging = vtkm::ColorSpace::Diverging; vtkm::cont::ColorTable table(rgbspace); VTKM_TEST_ASSERT(table.GetColorSpace() == rgbspace, "color space not saved"); @@ -90,10 +90,10 @@ public: static void TestLoadPresets() { vtkm::Range range{ 0.0, 1.0 }; - auto rgbspace = vtkm::cont::ColorSpace::RGB; - auto hsvspace = vtkm::cont::ColorSpace::HSV; - auto labspace = vtkm::cont::ColorSpace::LAB; - auto diverging = vtkm::cont::ColorSpace::DIVERGING; + auto rgbspace = vtkm::ColorSpace::RGB; + auto hsvspace = vtkm::ColorSpace::HSV; + auto labspace = vtkm::ColorSpace::Lab; + auto diverging = vtkm::ColorSpace::Diverging; { vtkm::cont::ColorTable table(rgbspace); @@ -103,7 +103,7 @@ public: VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset"); VTKM_TEST_ASSERT(table.GetNumberOfPoints() == 3); - VTKM_TEST_ASSERT(table.LoadPreset(vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED)); + VTKM_TEST_ASSERT(table.LoadPreset(vtkm::cont::ColorTable::Preset::CoolToWarmExtended)); VTKM_TEST_ASSERT(table.GetColorSpace() == labspace, "color space not switched when loading preset"); VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset"); @@ -140,24 +140,24 @@ public: VTKM_TEST_ASSERT(table.GetNumberOfPoints() > 0, "Issue loading preset ", name); } - auto presetEnum = { vtkm::cont::ColorTable::Preset::DEFAULT, - vtkm::cont::ColorTable::Preset::COOL_TO_WARM, - vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED, - vtkm::cont::ColorTable::Preset::VIRIDIS, - vtkm::cont::ColorTable::Preset::INFERNO, - vtkm::cont::ColorTable::Preset::PLASMA, - vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION, - vtkm::cont::ColorTable::Preset::X_RAY, - vtkm::cont::ColorTable::Preset::GREEN, - vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE, - vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE, - vtkm::cont::ColorTable::Preset::GRAY_TO_RED, - vtkm::cont::ColorTable::Preset::COLD_AND_HOT, - vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE, - vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE, - vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM, - vtkm::cont::ColorTable::Preset::JET, - vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED }; + auto presetEnum = { vtkm::cont::ColorTable::Preset::Default, + vtkm::cont::ColorTable::Preset::CoolToWarm, + vtkm::cont::ColorTable::Preset::CoolToWarmExtended, + vtkm::cont::ColorTable::Preset::Viridis, + vtkm::cont::ColorTable::Preset::Inferno, + vtkm::cont::ColorTable::Preset::Plasma, + vtkm::cont::ColorTable::Preset::BlackBodyRadiation, + vtkm::cont::ColorTable::Preset::XRay, + vtkm::cont::ColorTable::Preset::Green, + vtkm::cont::ColorTable::Preset::BlackBlueWhite, + vtkm::cont::ColorTable::Preset::BlueToOrange, + vtkm::cont::ColorTable::Preset::GrayToRed, + vtkm::cont::ColorTable::Preset::ColdAndHot, + vtkm::cont::ColorTable::Preset::BlueGreenOrange, + vtkm::cont::ColorTable::Preset::YellowGrayBlue, + vtkm::cont::ColorTable::Preset::RainbowUniform, + vtkm::cont::ColorTable::Preset::Jet, + vtkm::cont::ColorTable::Preset::RainbowDesaturated }; for (vtkm::cont::ColorTable::Preset preset : presetEnum) { vtkm::cont::ColorTable table(preset); @@ -172,7 +172,7 @@ public: vtkm::Range range{ 0.0, 1.0 }; vtkm::Vec rgb1{ 0.0f, 1.0f, 0.0f }; vtkm::Vec rgb2{ 1.0f, 0.0f, 1.0f }; - auto rgbspace = vtkm::cont::ColorSpace::RGB; + auto rgbspace = vtkm::ColorSpace::RGB; vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace); VTKM_TEST_ASSERT(table.GetClamping() == true, "clamping not setup properly"); @@ -194,7 +194,7 @@ public: vtkm::Range range{ -1.0, 2.0 }; vtkm::Vec rgb1{ 0.0f, 1.0f, 0.0f }; vtkm::Vec rgb2{ 1.0f, 0.0f, 1.0f }; - auto rgbspace = vtkm::cont::ColorSpace::RGB; + auto rgbspace = vtkm::ColorSpace::RGB; vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace); table.SetClampingOff(); @@ -228,7 +228,7 @@ public: //implement a blue2yellow color table vtkm::Vec rgb1{ 0.0f, 0.0f, 1.0f }; vtkm::Vec rgb2{ 1.0f, 1.0f, 0.0f }; - auto lab = vtkm::cont::ColorSpace::LAB; + auto lab = vtkm::ColorSpace::Lab; vtkm::cont::ColorTable table(range, rgb1, rgb2, lab); table.AddPoint(0.0, vtkm::Vec{ 0.5f, 0.5f, 0.5f }); @@ -266,7 +266,7 @@ public: std::cout << "Test Add Points" << std::endl; vtkm::Range range{ -20, 20.0 }; - auto rgbspace = vtkm::cont::ColorSpace::RGB; + auto rgbspace = vtkm::ColorSpace::RGB; vtkm::cont::ColorTable table(rgbspace); table.AddPoint(-10.0, vtkm::Vec{ 0.0f, 1.0f, 1.0f }); @@ -291,9 +291,9 @@ public: std::cout << "Test Add Segments" << std::endl; vtkm::Range range{ 0.0, 50.0 }; - auto diverging = vtkm::cont::ColorSpace::DIVERGING; + auto diverging = vtkm::ColorSpace::Diverging; - vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM); + vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm); VTKM_TEST_ASSERT(table.GetColorSpace() == diverging, "color space not switched when loading preset"); @@ -332,7 +332,7 @@ public: { std::cout << "Test Remove Points" << std::endl; - auto hsv = vtkm::cont::ColorSpace::HSV; + auto hsv = vtkm::ColorSpace::HSV; vtkm::cont::ColorTable table(hsv); //implement Blue to Red Rainbow color table @@ -370,7 +370,7 @@ public: std::cout << " Change Color Space" << std::endl; vtkm::cont::ArrayHandle colors_rgb; - table.SetColorSpace(vtkm::cont::ColorSpace::RGB); + table.SetColorSpace(vtkm::ColorSpace::RGB); table.Map(field, colors_rgb); CheckColors(colors_rgb, @@ -386,7 +386,7 @@ public: { std::cout << "Test Opacity Only Points" << std::endl; - auto hsv = vtkm::cont::ColorSpace::HSV; + auto hsv = vtkm::ColorSpace::HSV; vtkm::cont::ColorTable table(hsv); //implement only a color table @@ -430,7 +430,7 @@ public: using namespace vtkm::worklet::colorconversion; - vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::GREEN); + vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::Green); VTKM_TEST_ASSERT((table.GetRange() == vtkm::Range{ 0.0, 1.0 }), "loading linear green table failed with wrong range"); VTKM_TEST_ASSERT((table.GetNumberOfPoints() == 21), @@ -454,7 +454,7 @@ public: { std::cout << "Test Sampling" << std::endl; - vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::GREEN); + vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::Green); VTKM_TEST_ASSERT((table.GetRange() == vtkm::Range{ 0.0, 1.0 }), "loading linear green table failed with wrong range"); VTKM_TEST_ASSERT((table.GetNumberOfPoints() == 21), @@ -473,7 +473,7 @@ public: //build a color table with clamping off and verify that sampling works vtkm::Range range{ 0.0, 50.0 }; - vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM); + vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm); table.RescaleToRange(range); table.SetClampingOff(); table.SetAboveRangeColor(vtkm::Vec{ 1.0f, 0.0f, 0.0f }); //red diff --git a/vtkm/exec/ColorTable.h b/vtkm/exec/ColorTable.h index 2f74b0286..92a689024 100644 --- a/vtkm/exec/ColorTable.h +++ b/vtkm/exec/ColorTable.h @@ -10,85 +10,121 @@ #ifndef vtk_m_exec_ColorTable_h #define vtk_m_exec_ColorTable_h -#include +#include +#include + +namespace vtkm +{ + +enum struct ColorSpace +{ + RGB, + HSV, + HSVWrap, + Lab, + Diverging +}; + +} // namespace vtkm namespace vtkm { namespace exec { -class VTKM_ALWAYS_EXPORT ColorTableBase : public vtkm::VirtualObjectBase +class VTKM_ALWAYS_EXPORT ColorTable { public: - inline VTKM_EXEC vtkm::Vec MapThroughColorSpace(double) const; + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpace(vtkm::Float64) const; - VTKM_EXEC virtual vtkm::Vec MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const = 0; + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpace(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const; - inline VTKM_EXEC float MapThroughOpacitySpace(double value) const; + inline VTKM_EXEC vtkm::Float32 MapThroughOpacitySpace(vtkm::Float64 value) const; - double const* ColorNodes = nullptr; - vtkm::Vec const* RGB = nullptr; + vtkm::ColorSpace Space; - double const* ONodes = nullptr; - float const* Alpha = nullptr; - vtkm::Vec const* MidSharp = nullptr; + vtkm::Float64 const* ColorNodes = nullptr; + vtkm::Vec3f_32 const* RGB = nullptr; + + vtkm::Float64 const* ONodes = nullptr; + vtkm::Float32 const* Alpha = nullptr; + vtkm::Vec2f_32 const* MidSharp = nullptr; vtkm::Int32 ColorSize = 0; vtkm::Int32 OpacitySize = 0; - vtkm::Vec NaNColor = { 0.5f, 0.0f, 0.0f }; - vtkm::Vec BelowRangeColor = { 0.0f, 0.0f, 0.0f }; - vtkm::Vec AboveRangeColor = { 0.0f, 0.0f, 0.0f }; + vtkm::Vec3f_32 NaNColor = { 0.5f, 0.0f, 0.0f }; + vtkm::Vec3f_32 BelowRangeColor = { 0.0f, 0.0f, 0.0f }; + vtkm::Vec3f_32 AboveRangeColor = { 0.0f, 0.0f, 0.0f }; bool UseClamping = true; private: - inline VTKM_EXEC void FindColors(double value, - vtkm::Vec& first, - vtkm::Vec& second, - float& weight) const; + inline VTKM_EXEC void FindColors(vtkm::Float64 value, + vtkm::Vec3f_32& first, + vtkm::Vec3f_32& second, + vtkm::Float32& weight) const; + + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceRGB(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const; + + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceHSV(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const; + + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceHSVWrap(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const; + + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceLab(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const; + + inline VTKM_EXEC vtkm::Vec3f_32 MapThroughColorSpaceDiverging(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const; }; -class VTKM_ALWAYS_EXPORT ColorTableRGB final : public ColorTableBase +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableBase + : public vtkm::exec::ColorTable { -public: - inline VTKM_EXEC vtkm::Vec MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const; }; -class VTKM_ALWAYS_EXPORT ColorTableHSV final : public ColorTableBase +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableRGB final + : public ColorTable { public: - inline VTKM_EXEC vtkm::Vec MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const; + ColorTableRGB() { this->Space = vtkm::ColorSpace::RGB; } }; -class VTKM_ALWAYS_EXPORT ColorTableHSVWrap final : public ColorTableBase +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableHSV final + : public ColorTable { public: - inline VTKM_EXEC vtkm::Vec MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const; + ColorTableHSV() { this->Space = vtkm::ColorSpace::HSV; } }; -class VTKM_ALWAYS_EXPORT ColorTableLab final : public ColorTableBase +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableHSVWrap final + : public ColorTable { public: - inline VTKM_EXEC vtkm::Vec MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const; + ColorTableHSVWrap() { this->Space = vtkm::ColorSpace::HSVWrap; } }; -class VTKM_ALWAYS_EXPORT ColorTableDiverging final : public ColorTableBase +class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Use vtkm::exec::ColorTable.") ColorTableLab final + : public ColorTable { public: - inline VTKM_EXEC vtkm::Vec MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const; + ColorTableLab() { this->Space = vtkm::ColorSpace::Lab; } +}; + +class VTKM_ALWAYS_EXPORT ColorTableDiverging final : public ColorTable +{ +public: + ColorTableDiverging() { this->Space = vtkm::ColorSpace::Diverging; } }; } } diff --git a/vtkm/exec/ColorTable.hxx b/vtkm/exec/ColorTable.hxx index dde4bd219..29b91693c 100644 --- a/vtkm/exec/ColorTable.hxx +++ b/vtkm/exec/ColorTable.hxx @@ -21,14 +21,14 @@ namespace detail { VTKM_EXEC -inline void RGBToHSV(const vtkm::Vec& rgb, vtkm::Vec& hsv) +inline void RGBToHSV(const vtkm::Vec3f_32& rgb, vtkm::Vec3f_32& hsv) { - constexpr float onethird = 1.0f / 3.0f; - constexpr float onesixth = 1.0f / 6.0f; - constexpr float twothird = 2.0f / 3.0f; + constexpr vtkm::Float32 onethird = 1.0f / 3.0f; + constexpr vtkm::Float32 onesixth = 1.0f / 6.0f; + constexpr vtkm::Float32 twothird = 2.0f / 3.0f; - const float cmax = vtkm::Max(rgb[0], vtkm::Max(rgb[1], rgb[2])); - const float cmin = vtkm::Min(rgb[0], vtkm::Min(rgb[1], rgb[2])); + const vtkm::Float32 cmax = vtkm::Max(rgb[0], vtkm::Max(rgb[1], rgb[2])); + const vtkm::Float32 cmin = vtkm::Min(rgb[0], vtkm::Min(rgb[1], rgb[2])); hsv[0] = 0.0f; hsv[1] = 0.0f; @@ -57,13 +57,13 @@ inline void RGBToHSV(const vtkm::Vec& rgb, vtkm::Vec& hsv) } VTKM_EXEC -inline vtkm::Vec HSVToRGB(const vtkm::Vec& hsv) +inline vtkm::Vec3f_32 HSVToRGB(const vtkm::Vec3f_32& hsv) { - vtkm::Vec rgb; - constexpr float onethird = 1.0f / 3.0f; - constexpr float onesixth = 1.0f / 6.0f; - constexpr float twothird = 2.0f / 3.0f; - constexpr float fivesixth = 5.0f / 6.0f; + vtkm::Vec3f_32 rgb; + constexpr vtkm::Float32 onethird = 1.0f / 3.0f; + constexpr vtkm::Float32 onesixth = 1.0f / 6.0f; + constexpr vtkm::Float32 twothird = 2.0f / 3.0f; + constexpr vtkm::Float32 fivesixth = 5.0f / 6.0f; // compute RGB from HSV if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red @@ -115,7 +115,7 @@ inline vtkm::Vec HSVToRGB(const vtkm::Vec& hsv) } VTKM_EXEC -inline void RGBToLab(const vtkm::Vec& rgb, vtkm::Vec& lab) +inline void RGBToLab(const vtkm::Vec3f_32& rgb, vtkm::Vec3f_32& lab) { // clang-format off @@ -128,9 +128,9 @@ inline void RGBToLab(const vtkm::Vec& rgb, vtkm::Vec& lab) // management. OpenGL is agnostic on its RGB color space, but it is reasonable // to assume it is close to this one. { //rgb to xyz start ( lab == xyz ) - float r = rgb[0]; - float g = rgb[1]; - float b = rgb[2]; + vtkm::Float32 r = rgb[0]; + vtkm::Float32 g = rgb[1]; + vtkm::Float32 b = rgb[2]; if ( r > 0.04045f ) r = vtkm::Pow(( r + 0.055f ) / 1.055f, 2.4f); else r = r / 12.92f; if ( g > 0.04045f ) g = vtkm::Pow(( g + 0.055f ) / 1.055f, 2.4f); @@ -145,15 +145,15 @@ inline void RGBToLab(const vtkm::Vec& rgb, vtkm::Vec& lab) } //rgb to xyz end ( lab == xyz ) //xyz to lab start - constexpr float onethird = 1.0f / 3.0f; - constexpr float sixteen_onesixteen = 16.0f / 116.0f; + constexpr vtkm::Float32 onethird = 1.0f / 3.0f; + constexpr vtkm::Float32 sixteen_onesixteen = 16.0f / 116.0f; - constexpr float ref_X = 0.9505f; - constexpr float ref_Y = 1.000f; - constexpr float ref_Z = 1.089f; - float var_X = lab[0] / ref_X; - float var_Y = lab[1] / ref_Y; - float var_Z = lab[2] / ref_Z; + constexpr vtkm::Float32 ref_X = 0.9505f; + constexpr vtkm::Float32 ref_Y = 1.000f; + constexpr vtkm::Float32 ref_Z = 1.089f; + vtkm::Float32 var_X = lab[0] / ref_X; + vtkm::Float32 var_Y = lab[1] / ref_Y; + vtkm::Float32 var_Z = lab[2] / ref_Z; if ( var_X > 0.008856f ) var_X = vtkm::Pow(var_X, onethird); else var_X = ( 7.787f * var_X ) + sixteen_onesixteen; @@ -170,12 +170,12 @@ inline void RGBToLab(const vtkm::Vec& rgb, vtkm::Vec& lab) } VTKM_EXEC -inline vtkm::Vec LabToRGB(const vtkm::Vec& lab) +inline vtkm::Vec3f_32 LabToRGB(const vtkm::Vec3f_32& lab) { // clang-format off - vtkm::Vec rgb; + vtkm::Vec3f_32 rgb; { //lab to xyz start ( rgb == xyz ) - constexpr float sixteen_onesixteen = 16.0f / 116.0f; + constexpr vtkm::Float32 sixteen_onesixteen = 16.0f / 116.0f; //notice that we are mapping L => g, a => r, and b => b rgb[1] = ( lab[0] + 16.0f ) / 116.0f; @@ -190,22 +190,22 @@ inline vtkm::Vec LabToRGB(const vtkm::Vec& lab) if ( vtkm::Pow(rgb[2],3) > 0.008856f ) rgb[2] = vtkm::Pow(rgb[2],3); else rgb[2] = ( rgb[2] - sixteen_onesixteen ) / 7.787f; - constexpr float ref_X = 0.9505f; - constexpr float ref_Y = 1.000f; - constexpr float ref_Z = 1.089f; + constexpr vtkm::Float32 ref_X = 0.9505f; + constexpr vtkm::Float32 ref_Y = 1.000f; + constexpr vtkm::Float32 ref_Z = 1.089f; rgb[0] *= ref_X; //Observer= 2 deg Illuminant= D65 rgb[1] *= ref_Y; rgb[2] *= ref_Z; } // lab to xyz end //xyz to rgb start - rgb = vtkm::Vec( + rgb = vtkm::Vec3f_32( rgb[0] * 3.2406f + rgb[1] * -1.5372f + rgb[2] * -0.4986f, rgb[0] * -0.9689f + rgb[1] * 1.8758f + rgb[2] * 0.0415f, rgb[0] * 0.0557f + rgb[1] * -0.2040f + rgb[2] * 1.0570f); - float& r = rgb[0]; - float& g = rgb[1]; - float& b = rgb[2]; + vtkm::Float32& r = rgb[0]; + vtkm::Float32& g = rgb[1]; + vtkm::Float32& b = rgb[2]; // The following performs a "gamma correction" specified by the sRGB color // space. sRGB is defined by a canonical definition of a display monitor and @@ -215,7 +215,7 @@ inline vtkm::Vec LabToRGB(const vtkm::Vec& lab) // several applications including Adobe Photoshop and Microsoft Windows color // management. OpenGL is agnostic on its RGB color space, but it is reasonable // to assume it is close to this one. - constexpr float one_twopointfour = ( 1.0f / 2.4f ); + constexpr vtkm::Float32 one_twopointfour = ( 1.0f / 2.4f ); if (r > 0.0031308f) r = 1.055f * (vtkm::Pow(r, one_twopointfour)) - 0.055f; else r = 12.92f * r; if (g > 0.0031308f) g = 1.055f * (vtkm::Pow(g ,one_twopointfour)) - 0.055f; @@ -226,7 +226,7 @@ inline vtkm::Vec LabToRGB(const vtkm::Vec& lab) // Clip colors. ideally we would do something that is perceptually closest // (since we can see colors outside of the display gamut), but this seems to // work well enough. - const float maxVal = vtkm::Max(r, vtkm::Max(g,b)); + const vtkm::Float32 maxVal = vtkm::Max(r, vtkm::Max(g,b)); if (maxVal > 1.0f) { r /= maxVal; @@ -243,14 +243,14 @@ inline vtkm::Vec LabToRGB(const vtkm::Vec& lab) // Convert to a special polar version of CIELAB (useful for creating // continuous diverging color maps). VTKM_EXEC -inline void LabToMsh(const vtkm::Vec& lab, vtkm::Vec& msh) +inline void LabToMsh(const vtkm::Vec3f_32& lab, vtkm::Vec3f_32& msh) { - const float& L = lab[0]; - const float& a = lab[1]; - const float& b = lab[2]; - float& M = msh[0]; - float& s = msh[1]; - float& h = msh[2]; + const vtkm::Float32& L = lab[0]; + const vtkm::Float32& a = lab[1]; + const vtkm::Float32& b = lab[2]; + vtkm::Float32& M = msh[0]; + vtkm::Float32& s = msh[1]; + vtkm::Float32& h = msh[2]; M = vtkm::Sqrt(L * L + a * a + b * b); s = (M > 0.001f) ? vtkm::ACos(L / M) : 0.0f; @@ -260,23 +260,23 @@ inline void LabToMsh(const vtkm::Vec& lab, vtkm::Vec& msh) // Convert from a special polar version of CIELAB (useful for creating // continuous diverging color maps). VTKM_EXEC -inline vtkm::Vec MshToLab(const vtkm::Vec& msh) +inline vtkm::Vec3f_32 MshToLab(const vtkm::Vec3f_32& msh) { - const float& M = msh[0]; - const float& s = msh[1]; - const float& h = msh[2]; - vtkm::Vec r( + const vtkm::Float32& M = msh[0]; + const vtkm::Float32& s = msh[1]; + const vtkm::Float32& h = msh[2]; + vtkm::Vec3f_32 r( M * vtkm::Cos(s), M * vtkm::Sin(s) * vtkm::Cos(h), M * vtkm::Sin(s) * vtkm::Sin(h)); return r; } // Given two angular orientations, returns the smallest angle between the two. VTKM_EXEC -inline float DivergingAngleDiff(float a1, float a2) +inline vtkm::Float32 DivergingAngleDiff(vtkm::Float32 a1, vtkm::Float32 a2) { - constexpr float f_pi = vtkm::Pif(); - constexpr float f_two_pi = vtkm::TwoPif(); - float adiff = a1 - a2; + constexpr vtkm::Float32 f_pi = vtkm::Pif(); + constexpr vtkm::Float32 f_two_pi = vtkm::TwoPif(); + vtkm::Float32 adiff = a1 - a2; if (adiff < 0.0f) adiff = -adiff; while (adiff >= f_two_pi) @@ -289,9 +289,9 @@ inline float DivergingAngleDiff(float a1, float a2) // For the case when interpolating from a saturated color to an unsaturated // color, find a hue for the unsaturated color that makes sense. VTKM_EXEC -inline float DivergingAdjustHue(const vtkm::Vec& msh, float unsatM) +inline vtkm::Float32 DivergingAdjustHue(const vtkm::Vec3f_32& msh, vtkm::Float32 unsatM) { - const float sinS = vtkm::Sin(msh[1]); + const vtkm::Float32 sinS = vtkm::Sin(msh[1]); if (msh[0] >= unsatM - 0.1f) { @@ -302,9 +302,10 @@ inline float DivergingAdjustHue(const vtkm::Vec& msh, float unsatM) { // This equation is designed to make the perceptual change of the // interpolation to be close to constant. - float hueSpin = msh[1] * vtkm::Sqrt(unsatM * unsatM - msh[0] * msh[0]) / (msh[0] * sinS); + vtkm::Float32 hueSpin = + msh[1] * vtkm::Sqrt(unsatM * unsatM - msh[0] * msh[0]) / (msh[0] * sinS); - constexpr float one_third_pi = vtkm::Pi_3f(); + constexpr vtkm::Float32 one_third_pi = vtkm::Pi_3f(); // Spin hue away from 0 except in purple hues. if (msh[2] > -one_third_pi) { @@ -322,10 +323,10 @@ inline float DivergingAdjustHue(const vtkm::Vec& msh, float unsatM) //--------------------------------------------------------------------------- VTKM_EXEC -vtkm::Vec ColorTableBase::MapThroughColorSpace(double value) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpace(vtkm::Float64 value) const { - vtkm::Vec rgb1, rgb2; - float weight = 0; + vtkm::Vec3f_32 rgb1, rgb2; + vtkm::Float32 weight = 0; this->FindColors(value, rgb1, rgb2, weight); if (weight == 0) { @@ -343,10 +344,31 @@ vtkm::Vec ColorTableBase::MapThroughColorSpace(double value) const //--------------------------------------------------------------------------- VTKM_EXEC -void ColorTableBase::FindColors(double value, - vtkm::Vec& rgb1, - vtkm::Vec& rgb2, - float& weight) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpace(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const +{ + switch (this->Space) + { + case vtkm::ColorSpace::RGB: + return this->MapThroughColorSpaceRGB(rgb1, rgb2, weight); + case vtkm::ColorSpace::HSV: + return this->MapThroughColorSpaceHSV(rgb1, rgb2, weight); + case vtkm::ColorSpace::HSVWrap: + return this->MapThroughColorSpaceHSVWrap(rgb1, rgb2, weight); + case vtkm::ColorSpace::Lab: + return this->MapThroughColorSpaceLab(rgb1, rgb2, weight); + case vtkm::ColorSpace::Diverging: + return this->MapThroughColorSpaceDiverging(rgb1, rgb2, weight); + } +} + +//--------------------------------------------------------------------------- +VTKM_EXEC +void ColorTable::FindColors(vtkm::Float64 value, + vtkm::Vec3f_32& rgb1, + vtkm::Vec3f_32& rgb2, + vtkm::Float32& weight) const { // All the special cases have equivalent rgb1 and rgb2 values so we // set the weight to 0.0f as a default @@ -402,13 +424,13 @@ void ColorTableBase::FindColors(double value, const auto w = (value - this->ColorNodes[first]) / (this->ColorNodes[second] - this->ColorNodes[first]); - weight = static_cast(w); + weight = static_cast(w); } } //--------------------------------------------------------------------------- VTKM_EXEC -float ColorTableBase::MapThroughOpacitySpace(double value) const +vtkm::Float32 ColorTable::MapThroughOpacitySpace(vtkm::Float64 value) const { if (vtkm::IsNan(value)) { //If we are trying to find the opacity of NaN use a constant of 1.0 @@ -442,7 +464,7 @@ float ColorTableBase::MapThroughOpacitySpace(double value) const } } const auto w = (value - this->ONodes[first]) / (this->ONodes[second] - this->ONodes[first]); - float weight = static_cast(w); + vtkm::Float32 weight = static_cast(w); //we only need the previous midpoint and sharpness as they control this region const auto& alpha1 = this->Alpha[first]; @@ -490,20 +512,20 @@ float ColorTableBase::MapThroughOpacitySpace(double value) const } // Compute some coefficients we will need for the hermite curve - const float ww = weight * weight; - const float www = weight * weight * weight; + const vtkm::Float32 ww = weight * weight; + const vtkm::Float32 www = weight * weight * weight; - const float h1 = 2.0f * www - 3.0f * ww + 1.0f; - const float h2 = -2.0f * www + 3.0f * ww; - const float h3 = www - 2.0f * ww + weight; - const float h4 = www - ww; + const vtkm::Float32 h1 = 2.0f * www - 3.0f * ww + 1.0f; + const vtkm::Float32 h2 = -2.0f * www + 3.0f * ww; + const vtkm::Float32 h3 = www - 2.0f * ww + weight; + const vtkm::Float32 h4 = www - ww; // Use one slope for both end points - const float slope = alpha2 - alpha1; - const float t = (1.0f - midsharp[1]) * slope; + const vtkm::Float32 slope = alpha2 - alpha1; + const vtkm::Float32 t = (1.0f - midsharp[1]) * slope; // Compute the value - float result = h1 * alpha1 + h2 * alpha2 + h3 * t + h4 * t; + vtkm::Float32 result = h1 * alpha1 + h2 * alpha2 + h3 * t + h4 * t; // Final error check to make sure we don't go outside // the Y range @@ -515,20 +537,20 @@ float ColorTableBase::MapThroughOpacitySpace(double value) const } //--------------------------------------------------------------------------- VTKM_EXEC -vtkm::Vec ColorTableRGB::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceRGB(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const { return vtkm::Lerp(rgb1, rgb2, weight); } //--------------------------------------------------------------------------- VTKM_EXEC -vtkm::Vec ColorTableHSV::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceHSV(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const { - vtkm::Vec hsv1, hsv2; + vtkm::Vec3f_32 hsv1, hsv2; detail::RGBToHSV(rgb1, hsv1); detail::RGBToHSV(rgb2, hsv2); @@ -542,15 +564,15 @@ vtkm::Vec ColorTableHSV::MapThroughColorSpace(const vtkm::Vec ColorTableHSVWrap::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceHSVWrap(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const { - vtkm::Vec hsv1, hsv2; + vtkm::Vec3f_32 hsv1, hsv2; detail::RGBToHSV(rgb1, hsv1); detail::RGBToHSV(rgb2, hsv2); - const float diff = hsv1[0] - hsv2[0]; + const vtkm::Float32 diff = hsv1[0] - hsv2[0]; if (diff > 0.5f) { hsv1[0] -= 1.0f; @@ -570,11 +592,11 @@ vtkm::Vec ColorTableHSVWrap::MapThroughColorSpace(const vtkm::Vec ColorTableLab::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceLab(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const { - vtkm::Vec lab1, lab2; + vtkm::Vec3f_32 lab1, lab2; detail::RGBToLab(rgb1, lab1); detail::RGBToLab(rgb2, lab2); @@ -585,27 +607,27 @@ vtkm::Vec ColorTableLab::MapThroughColorSpace(const vtkm::Vec ColorTableDiverging::MapThroughColorSpace(const vtkm::Vec& rgb1, - const vtkm::Vec& rgb2, - float weight) const +vtkm::Vec3f_32 ColorTable::MapThroughColorSpaceDiverging(const vtkm::Vec3f_32& rgb1, + const vtkm::Vec3f_32& rgb2, + vtkm::Float32 weight) const { - vtkm::Vec lab1, lab2; + vtkm::Vec3f_32 lab1, lab2; detail::RGBToLab(rgb1, lab1); detail::RGBToLab(rgb2, lab2); - vtkm::Vec msh1, msh2; + vtkm::Vec3f_32 msh1, msh2; detail::LabToMsh(lab1, msh1); detail::LabToMsh(lab2, msh2); // If the endpoints are distinct saturated colors, then place white in between // them. - constexpr float one_third_pi = vtkm::Pi_3f(); + constexpr vtkm::Float32 one_third_pi = vtkm::Pi_3f(); if ((msh1[1] > 0.05f) && (msh2[1] > 0.05f) && (detail::DivergingAngleDiff(msh1[2], msh2[2]) > one_third_pi)) { // Insert the white midpoint by setting one end to white and adjusting the // scalar value. - float Mmid = vtkm::Max(msh1[0], msh2[0]); + vtkm::Float32 Mmid = vtkm::Max(msh1[0], msh2[0]); Mmid = vtkm::Max(88.0f, Mmid); if (weight < 0.5f) { @@ -640,20 +662,6 @@ vtkm::Vec ColorTableDiverging::MapThroughColorSpace(const vtkm::Vec -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableRGB); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableHSV); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableHSVWrap); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableLab); -VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::exec::ColorTableDiverging); -#endif +} // namespace vtkm::exec #endif diff --git a/vtkm/filter/testing/UnitTestFieldToColors.cxx b/vtkm/filter/testing/UnitTestFieldToColors.cxx index 38648abe1..96914ca80 100644 --- a/vtkm/filter/testing/UnitTestFieldToColors.cxx +++ b/vtkm/filter/testing/UnitTestFieldToColors.cxx @@ -22,7 +22,7 @@ void TestFieldToColors() //build a color table with clamping off and verify that sampling works vtkm::Range range{ 0.0, 50.0 }; - vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM); + vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm); table.RescaleToRange(range); table.SetClampingOff(); table.SetAboveRangeColor(vtkm::Vec{ 1.0f, 0.0f, 0.0f }); //red diff --git a/vtkm/rendering/Actor.cxx b/vtkm/rendering/Actor.cxx index e60d07c69..92825d1fb 100644 --- a/vtkm/rendering/Actor.cxx +++ b/vtkm/rendering/Actor.cxx @@ -44,7 +44,7 @@ struct Actor::InternalsType InternalsType(const vtkm::cont::DynamicCellSet& cells, const vtkm::cont::CoordinateSystem& coordinates, const vtkm::cont::Field& scalarField, - const vtkm::cont::ColorTable& colorTable = vtkm::cont::ColorTable::Preset::DEFAULT) + const vtkm::cont::ColorTable& colorTable = vtkm::cont::ColorTable::Preset::Default) : Cells(cells) , Coordinates(coordinates) , ScalarField(scalarField) diff --git a/vtkm/rendering/ColorBarAnnotation.cxx b/vtkm/rendering/ColorBarAnnotation.cxx index 4df85de24..f184b4bf0 100644 --- a/vtkm/rendering/ColorBarAnnotation.cxx +++ b/vtkm/rendering/ColorBarAnnotation.cxx @@ -17,7 +17,7 @@ namespace rendering { ColorBarAnnotation::ColorBarAnnotation() - : ColorTable(vtkm::cont::ColorSpace::LAB) + : ColorTable(vtkm::ColorSpace::Lab) , Position(vtkm::Range(-0.88, +0.88), vtkm::Range(+0.87, +0.92), vtkm::Range(0, 0)) , Horizontal(true) , FieldName("") diff --git a/vtkm/worklet/colorconversion/TransferFunction.h b/vtkm/worklet/colorconversion/TransferFunction.h index fa9d1deed..a08d485a2 100644 --- a/vtkm/worklet/colorconversion/TransferFunction.h +++ b/vtkm/worklet/colorconversion/TransferFunction.h @@ -23,7 +23,7 @@ namespace colorconversion struct TransferFunction : public vtkm::worklet::WorkletMapField { - TransferFunction(const vtkm::exec::ColorTableBase* table) + TransferFunction(const vtkm::exec::ColorTable table) : ColorTable(table) { } @@ -34,7 +34,7 @@ struct TransferFunction : public vtkm::worklet::WorkletMapField template VTKM_EXEC void operator()(const T& in, vtkm::Vec3ui_8& output) const { - vtkm::Vec rgb = this->ColorTable->MapThroughColorSpace(static_cast(in)); + vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); output[0] = colorconversion::ColorToUChar(rgb[0]); output[1] = colorconversion::ColorToUChar(rgb[1]); output[2] = colorconversion::ColorToUChar(rgb[2]); @@ -43,8 +43,8 @@ struct TransferFunction : public vtkm::worklet::WorkletMapField template VTKM_EXEC void operator()(const T& in, vtkm::Vec4ui_8& output) const { - vtkm::Vec rgb = this->ColorTable->MapThroughColorSpace(static_cast(in)); - float alpha = this->ColorTable->MapThroughOpacitySpace(static_cast(in)); + vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); + float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast(in)); output[0] = colorconversion::ColorToUChar(rgb[0]); output[1] = colorconversion::ColorToUChar(rgb[1]); output[2] = colorconversion::ColorToUChar(rgb[2]); @@ -54,21 +54,21 @@ struct TransferFunction : public vtkm::worklet::WorkletMapField template VTKM_EXEC void operator()(const T& in, vtkm::Vec& output) const { - output = this->ColorTable->MapThroughColorSpace(static_cast(in)); + output = this->ColorTable.MapThroughColorSpace(static_cast(in)); } template VTKM_EXEC void operator()(const T& in, vtkm::Vec& output) const { - vtkm::Vec rgb = this->ColorTable->MapThroughColorSpace(static_cast(in)); - float alpha = this->ColorTable->MapThroughOpacitySpace(static_cast(in)); + vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); + float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast(in)); output[0] = rgb[0]; output[1] = rgb[1]; output[2] = rgb[2]; output[3] = alpha; } - const vtkm::exec::ColorTableBase* ColorTable; + const vtkm::exec::ColorTable ColorTable; }; } } From 9465d26110f418e4c4b30b180a480f645ef82fcc Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 13:38:25 -0600 Subject: [PATCH 29/51] Adjust TransferFunction worklet to get color table as ExecObj argument Previously, the `TransferFunction` worklet required you to call `PrepareForExecution` on the `ColorTable` and give that to the constructor. Bad things can happen if the `ColorTable` used in the constructor does not match the device the worklet actually gets invoked on. Change this to make the `ColorTable` a worklet argument of type `ExecObj`. The dispatcher will automatically call `ColorTable::PrepareForInput` and guarantee that the devices match. --- vtkm/cont/ColorTable.hxx | 25 +++--------- vtkm/cont/testing/TestingColorTable.h | 9 +---- .../colorconversion/TransferFunction.h | 39 ++++++++++--------- 3 files changed, 28 insertions(+), 45 deletions(-) diff --git a/vtkm/cont/ColorTable.hxx b/vtkm/cont/ColorTable.hxx index 9a2b64db9..c6f161f49 100644 --- a/vtkm/cont/ColorTable.hxx +++ b/vtkm/cont/ColorTable.hxx @@ -26,23 +26,6 @@ namespace vtkm { namespace cont { -namespace detail -{ - -struct map_color_table -{ - template - inline bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const - { - vtkm::cont::Token token; - vtkm::worklet::colorconversion::TransferFunction transfer( - colors->PrepareForExecution(device, token)); - vtkm::cont::Invoker invoke(device); - invoke(transfer, std::forward(args)...); - return true; - } -}; -} //--------------------------------------------------------------------------- template @@ -123,14 +106,18 @@ template bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& rgbaOut) const { - return vtkm::cont::TryExecute(detail::map_color_table{}, this, values, rgbaOut); + vtkm::cont::Invoker invoke; + invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, *this, rgbaOut); + return true; } //--------------------------------------------------------------------------- template bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& rgbOut) const { - return vtkm::cont::TryExecute(detail::map_color_table{}, this, values, rgbOut); + vtkm::cont::Invoker invoke; + invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, *this, rgbOut); + return true; } //--------------------------------------------------------------------------- template diff --git a/vtkm/cont/testing/TestingColorTable.h b/vtkm/cont/testing/TestingColorTable.h index 63f254718..bf99edc73 100644 --- a/vtkm/cont/testing/TestingColorTable.h +++ b/vtkm/cont/testing/TestingColorTable.h @@ -439,13 +439,8 @@ public: auto samples = vtkm::cont::make_ArrayHandle({ 0.0, 0.5, 1.0 }); vtkm::cont::ArrayHandle colors; - { - vtkm::cont::Token token; - TransferFunction transfer(table.PrepareForExecution(DeviceAdapterTag{}, token)); - vtkm::worklet::DispatcherMapField dispatcher(transfer); - dispatcher.SetDevice(DeviceAdapterTag()); - dispatcher.Invoke(samples, colors); - } + vtkm::cont::Invoker invoke; + invoke(TransferFunction{}, samples, table, colors); CheckColors(colors, { { 14, 28, 31, 255 }, { 21, 150, 21, 255 }, { 255, 251, 230, 255 } }); } diff --git a/vtkm/worklet/colorconversion/TransferFunction.h b/vtkm/worklet/colorconversion/TransferFunction.h index a08d485a2..112f15513 100644 --- a/vtkm/worklet/colorconversion/TransferFunction.h +++ b/vtkm/worklet/colorconversion/TransferFunction.h @@ -23,28 +23,27 @@ namespace colorconversion struct TransferFunction : public vtkm::worklet::WorkletMapField { - TransferFunction(const vtkm::exec::ColorTable table) - : ColorTable(table) - { - } - - using ControlSignature = void(FieldIn in, FieldOut color); - using ExecutionSignature = void(_1, _2); + using ControlSignature = void(FieldIn in, ExecObject colorTable, FieldOut color); + using ExecutionSignature = void(_1, _2, _3); template - VTKM_EXEC void operator()(const T& in, vtkm::Vec3ui_8& output) const + VTKM_EXEC void operator()(const T& in, + const vtkm::exec::ColorTable& colorTable, + vtkm::Vec3ui_8& output) const { - vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); + vtkm::Vec rgb = colorTable.MapThroughColorSpace(static_cast(in)); output[0] = colorconversion::ColorToUChar(rgb[0]); output[1] = colorconversion::ColorToUChar(rgb[1]); output[2] = colorconversion::ColorToUChar(rgb[2]); } template - VTKM_EXEC void operator()(const T& in, vtkm::Vec4ui_8& output) const + VTKM_EXEC void operator()(const T& in, + const vtkm::exec::ColorTable& colorTable, + vtkm::Vec4ui_8& output) const { - vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); - float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast(in)); + vtkm::Vec rgb = colorTable.MapThroughColorSpace(static_cast(in)); + float alpha = colorTable.MapThroughOpacitySpace(static_cast(in)); output[0] = colorconversion::ColorToUChar(rgb[0]); output[1] = colorconversion::ColorToUChar(rgb[1]); output[2] = colorconversion::ColorToUChar(rgb[2]); @@ -52,23 +51,25 @@ struct TransferFunction : public vtkm::worklet::WorkletMapField } template - VTKM_EXEC void operator()(const T& in, vtkm::Vec& output) const + VTKM_EXEC void operator()(const T& in, + const vtkm::exec::ColorTable& colorTable, + vtkm::Vec3f_32& output) const { - output = this->ColorTable.MapThroughColorSpace(static_cast(in)); + output = colorTable.MapThroughColorSpace(static_cast(in)); } template - VTKM_EXEC void operator()(const T& in, vtkm::Vec& output) const + VTKM_EXEC void operator()(const T& in, + const vtkm::exec::ColorTable& colorTable, + vtkm::Vec4f_32& output) const { - vtkm::Vec rgb = this->ColorTable.MapThroughColorSpace(static_cast(in)); - float alpha = this->ColorTable.MapThroughOpacitySpace(static_cast(in)); + vtkm::Vec3f_32 rgb = colorTable.MapThroughColorSpace(static_cast(in)); + vtkm::Float32 alpha = colorTable.MapThroughOpacitySpace(static_cast(in)); output[0] = rgb[0]; output[1] = rgb[1]; output[2] = rgb[2]; output[3] = alpha; } - - const vtkm::exec::ColorTable ColorTable; }; } } From c6a4f9b79c48109feb473d770af72bc136f92bc1 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 15:04:03 -0600 Subject: [PATCH 30/51] Fix warning about return value --- vtkm/exec/ColorTable.hxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vtkm/exec/ColorTable.hxx b/vtkm/exec/ColorTable.hxx index 29b91693c..a802ce0d2 100644 --- a/vtkm/exec/ColorTable.hxx +++ b/vtkm/exec/ColorTable.hxx @@ -361,6 +361,8 @@ vtkm::Vec3f_32 ColorTable::MapThroughColorSpace(const vtkm::Vec3f_32& rgb1, case vtkm::ColorSpace::Diverging: return this->MapThroughColorSpaceDiverging(rgb1, rgb2, weight); } + // Should not get here, but some compilers give a warning if this is not here. + return vtkm::Vec3f_32{}; } //--------------------------------------------------------------------------- From 6a3ba4291b952c4beb48d7ea499940caa078ffc5 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 15:26:43 -0600 Subject: [PATCH 31/51] Fix warning about unused function --- vtkm/cont/ColorTable.cxx | 47 ++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/vtkm/cont/ColorTable.cxx b/vtkm/cont/ColorTable.cxx index f7af39f2b..7d2ec8bc2 100644 --- a/vtkm/cont/ColorTable.cxx +++ b/vtkm/cont/ColorTable.cxx @@ -200,33 +200,48 @@ inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) return rgb; } -// clang-format off -inline bool outside_vrange(double x) { return x < 0.0 || x > 1.0; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0 || x[2] < 0.0 || x[2] > 1.0; } -inline bool outside_vrange(float x) { return x < 0.0f || x > 1.0f; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f; } -inline bool outside_vrange(const vtkm::Vec& x) - { return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f || x[2] < 0.0f || x[2] > 1.0f; } +inline bool outside_vrange(double x) +{ + return x < 0.0 || x > 1.0; +} +inline bool outside_vrange(float x) +{ + return x < 0.0f || x > 1.0f; +} +template +inline bool outside_vrange(const vtkm::Vec& x) +{ + return outside_vrange(x[0]) || outside_vrange(x[1]); +} +template +inline bool outside_vrange(const vtkm::Vec& x) +{ + return outside_vrange(x[0]) || outside_vrange(x[1]) || outside_vrange(x[2]); +} -inline bool outside_range() { return false; } +inline bool outside_range() +{ + return false; +} template -inline bool outside_range(T&& t) { return outside_vrange(t); } +inline bool outside_range(T&& t) +{ + return outside_vrange(t); +} template -inline bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); } +inline bool outside_range(T&& t, U&& u) +{ + return outside_vrange(t) || outside_vrange(u); +} template inline bool outside_range(T&& t, U&& u, V&& v, Args&&... args) { return outside_vrange(t) || outside_vrange(u) || outside_vrange(v) || - outside_range(std::forward(args)...); + outside_range(std::forward(args)...); } -// clang-format on } namespace vtkm From 38bdfec40a479dad4f661d7dd2eb6891bdddf9a5 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 15:47:42 -0600 Subject: [PATCH 32/51] Move ColorTable::Sample methods to vtkm_cont There is little value to declare them `inline`. Instead, just have them compiled once in the `vtkm_cont` library. --- vtkm/cont/ColorTable.cxx | 176 +++++++++++++++++++++++++++++++++----- vtkm/cont/ColorTable.h | 24 +++--- vtkm/cont/ColorTable.hxx | 137 ----------------------------- vtkm/rendering/Canvas.cxx | 2 - vtkm/rendering/Mapper.cxx | 2 - 5 files changed, 167 insertions(+), 174 deletions(-) diff --git a/vtkm/cont/ColorTable.cxx b/vtkm/cont/ColorTable.cxx index 7d2ec8bc2..96fbdeaa1 100644 --- a/vtkm/cont/ColorTable.cxx +++ b/vtkm/cont/ColorTable.cxx @@ -24,14 +24,14 @@ template struct MinDelta { }; -// This value seems to work well for float ranges we have tested +// This value seems to work well for vtkm::Float32 ranges we have tested template <> -struct MinDelta +struct MinDelta { static constexpr int value = 2048; }; template <> -struct MinDelta +struct MinDelta { static constexpr vtkm::Int64 value = 2048L; }; @@ -46,12 +46,12 @@ struct MinRepresentable { }; template <> -struct MinRepresentable +struct MinRepresentable { static constexpr int value = 8388608; }; template <> -struct MinRepresentable +struct MinRepresentable { static constexpr vtkm::Int64 value = 4503599627370496L; }; @@ -71,7 +71,7 @@ inline bool rangeAlmostEqual(const vtkm::Range& r) } template -inline double expandRange(T r[2]) +inline vtkm::Float64 expandRange(T r[2]) { constexpr bool is_float32_type = std::is_same::value; using IRange = typename std::conditional::type; @@ -104,9 +104,9 @@ inline double expandRange(T r[2]) T result; std::memcpy(&result, irange + 1, sizeof(T)); - return static_cast(result); + return static_cast(result); } - return static_cast(r[1]); + return static_cast(r[1]); } inline vtkm::Range adjustRange(const vtkm::Range& r) @@ -127,29 +127,30 @@ inline vtkm::Range adjustRange(const vtkm::Range& r) // to avoid loss of precision whenever possible. That is why // we only modify the Max value vtkm::Range result = r; - if (r.Min > static_cast(std::numeric_limits::lowest()) && - r.Max < static_cast(std::numeric_limits::max())) - { //We've found it best to offset it in float space if the numbers + if (r.Min > static_cast(std::numeric_limits::lowest()) && + r.Max < static_cast(std::numeric_limits::max())) + { //We've found it best to offset it in vtkm::Float32 space if the numbers //lay inside that representable range - float frange[2] = { static_cast(r.Min), static_cast(r.Max) }; + vtkm::Float32 frange[2] = { static_cast(r.Min), + static_cast(r.Max) }; result.Max = expandRange(frange); } else { - double drange[2] = { r.Min, r.Max }; + vtkm::Float64 drange[2] = { r.Min, r.Max }; result.Max = expandRange(drange); } return result; } -inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) +inline vtkm::Vec3f_32 hsvTorgb(const vtkm::Vec3f_32& hsv) { - vtkm::Vec rgb; - constexpr float onethird = 1.0f / 3.0f; - constexpr float onesixth = 1.0f / 6.0f; - constexpr float twothird = 2.0f / 3.0f; - constexpr float fivesixth = 5.0f / 6.0f; + vtkm::Vec3f_32 rgb; + constexpr vtkm::Float32 onethird = 1.0f / 3.0f; + constexpr vtkm::Float32 onesixth = 1.0f / 6.0f; + constexpr vtkm::Float32 twothird = 2.0f / 3.0f; + constexpr vtkm::Float32 fivesixth = 5.0f / 6.0f; // compute RGB from HSV if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red @@ -200,11 +201,11 @@ inline vtkm::Vec hsvTorgb(const vtkm::Vec& hsv) return rgb; } -inline bool outside_vrange(double x) +inline bool outside_vrange(vtkm::Float64 x) { return x < 0.0 || x > 1.0; } -inline bool outside_vrange(float x) +inline bool outside_vrange(vtkm::Float32 x) { return x < 0.0f || x > 1.0f; } @@ -242,8 +243,89 @@ inline bool outside_range(T&& t, U&& u, V&& v, Args&&... args) return outside_vrange(t) || outside_vrange(u) || outside_vrange(v) || outside_range(std::forward(args)...); } + +template +inline vtkm::cont::ArrayHandle buildSampleHandle(vtkm::Int32 numSamples, + T start, + T end, + T inc, + bool appendNanAndRangeColors) +{ + + //number of samples + end + appendNanAndRangeColors + vtkm::Int32 allocationSize = (appendNanAndRangeColors) ? numSamples + 5 : numSamples + 1; + + vtkm::cont::ArrayHandle handle; + handle.Allocate(allocationSize); + + auto portal = handle.WritePortal(); + vtkm::Id index = 0; + + //Insert the below range first + if (appendNanAndRangeColors) + { + portal.Set(index++, std::numeric_limits::lowest()); //below + } + + //add number of samples which doesn't account for the end + T value = start; + for (vtkm::Int32 i = 0; i < numSamples; ++i, ++index, value += inc) + { + portal.Set(index, value); + } + portal.Set(index++, end); + + if (appendNanAndRangeColors) + { + //push back the last value again so that when lookups near the max value + //occur we don't need to clamp as if they are out-of-bounds they will + //land in the extra 'end' color + portal.Set(index++, end); + portal.Set(index++, std::numeric_limits::max()); //above + portal.Set(index++, vtkm::Nan()); //nan + } + + return handle; } +template +inline bool sampleColorTable(const vtkm::cont::ColorTable* self, + vtkm::Int32 numSamples, + OutputColors& colors, + vtkm::Float64 tolerance, + bool appendNanAndRangeColors) +{ + vtkm::Range r = self->GetRange(); + //We want the samples to start at Min, and end at Max so that means + //we want actually to interpolate numSample - 1 values. For example + //for range 0 - 1, we want the values 0, 0.5, and 1. + const vtkm::Float64 d_samples = static_cast(numSamples - 1); + const vtkm::Float64 d_delta = r.Length() / d_samples; + + if (r.Min > static_cast(std::numeric_limits::lowest()) && + r.Max < static_cast(std::numeric_limits::max())) + { + //we can try and see if Float32 space has enough resolution + const vtkm::Float32 f_samples = static_cast(numSamples - 1); + const vtkm::Float32 f_start = static_cast(r.Min); + const vtkm::Float32 f_delta = static_cast(r.Length()) / f_samples; + const vtkm::Float32 f_end = f_start + (f_delta * f_samples); + + if (vtkm::Abs(static_cast(f_end) - r.Max) <= tolerance && + vtkm::Abs(static_cast(f_delta) - d_delta) <= tolerance) + { + auto handle = + buildSampleHandle((numSamples - 1), f_start, f_end, f_delta, appendNanAndRangeColors); + return self->Map(handle, colors); + } + } + + //otherwise we need to use Float64 space + auto handle = buildSampleHandle((numSamples - 1), r.Min, r.Max, d_delta, appendNanAndRangeColors); + return self->Map(handle, colors); +} +} // anonymous namespace + namespace vtkm { namespace cont @@ -1072,6 +1154,58 @@ bool ColorTable::FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Floa return true; } +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::Float64 tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + samples.NumberOfSamples = numSamples; + samples.SampleRange = this->GetRange(); + return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); +} + +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::Float64 tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + samples.NumberOfSamples = numSamples; + samples.SampleRange = this->GetRange(); + return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); +} + +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle& colors, + vtkm::Float64 tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + return sampleColorTable(this, numSamples, colors, tolerance, false); +} + +//--------------------------------------------------------------------------- +bool ColorTable::Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle& colors, + vtkm::Float64 tolerance) const +{ + if (numSamples <= 1) + { + return false; + } + return sampleColorTable(this, numSamples, colors, tolerance, false); +} + //---------------------------------------------------------------------------- void ColorTable::UpdateArrayHandles() const { diff --git a/vtkm/cont/ColorTable.h b/vtkm/cont/ColorTable.h index 37cca608b..3ef59242a 100644 --- a/vtkm/cont/ColorTable.h +++ b/vtkm/cont/ColorTable.h @@ -663,9 +663,9 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - inline bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::Float64 tolerance = 0.002) const; + bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::Float64 tolerance = 0.002) const; /// \brief generate a sample lookup table using regular spaced samples along the range. /// @@ -678,9 +678,9 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - inline bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::Float64 tolerance = 0.002) const; + bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::Float64 tolerance = 0.002) const; /// \brief generate RGBA colors using regular spaced samples along the range. /// @@ -693,9 +693,9 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - inline bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle& colors, - vtkm::Float64 tolerance = 0.002) const; + bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle& colors, + vtkm::Float64 tolerance = 0.002) const; /// \brief generate RGB colors using regular spaced samples along the range. /// @@ -708,9 +708,9 @@ public: /// - ((max-min) / numSamples) * numSamples /// /// Note: This will return false if the number of samples is less than 2 - inline bool Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle& colors, - vtkm::Float64 tolerance = 0.002) const; + bool Sample(vtkm::Int32 numSamples, + vtkm::cont::ArrayHandle& colors, + vtkm::Float64 tolerance = 0.002) const; /// \brief returns a virtual object pointer of the exec color table diff --git a/vtkm/cont/ColorTable.hxx b/vtkm/cont/ColorTable.hxx index c6f161f49..0f8f02ed0 100644 --- a/vtkm/cont/ColorTable.hxx +++ b/vtkm/cont/ColorTable.hxx @@ -153,143 +153,6 @@ bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle, S>& using namespace vtkm::worklet::colorconversion; return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbOut); } - -namespace -{ - -template -inline vtkm::cont::ArrayHandle buildSampleHandle(vtkm::Int32 numSamples, - T start, - T end, - T inc, - bool appendNanAndRangeColors) -{ - - //number of samples + end + appendNanAndRangeColors - vtkm::Int32 allocationSize = (appendNanAndRangeColors) ? numSamples + 5 : numSamples + 1; - - vtkm::cont::ArrayHandle handle; - handle.Allocate(allocationSize); - - auto portal = handle.WritePortal(); - vtkm::Id index = 0; - - //Insert the below range first - if (appendNanAndRangeColors) - { - portal.Set(index++, std::numeric_limits::lowest()); //below - } - - //add number of samples which doesn't account for the end - T value = start; - for (vtkm::Int32 i = 0; i < numSamples; ++i, ++index, value += inc) - { - portal.Set(index, value); - } - portal.Set(index++, end); - - if (appendNanAndRangeColors) - { - //push back the last value again so that when lookups near the max value - //occur we don't need to clamp as if they are out-of-bounds they will - //land in the extra 'end' color - portal.Set(index++, end); - portal.Set(index++, std::numeric_limits::max()); //above - portal.Set(index++, vtkm::Nan()); //nan - } - - return handle; -} - -template -inline bool sampleColorTable(const ColorTable* self, - vtkm::Int32 numSamples, - OutputColors& colors, - double tolerance, - bool appendNanAndRangeColors) -{ - vtkm::Range r = self->GetRange(); - //We want the samples to start at Min, and end at Max so that means - //we want actually to interpolate numSample - 1 values. For example - //for range 0 - 1, we want the values 0, 0.5, and 1. - const double d_samples = static_cast(numSamples - 1); - const double d_delta = r.Length() / d_samples; - - if (r.Min > static_cast(std::numeric_limits::lowest()) && - r.Max < static_cast(std::numeric_limits::max())) - { - //we can try and see if float space has enough resolution - const float f_samples = static_cast(numSamples - 1); - const float f_start = static_cast(r.Min); - const float f_delta = static_cast(r.Length()) / f_samples; - const float f_end = f_start + (f_delta * f_samples); - - if (vtkm::Abs(static_cast(f_end) - r.Max) <= tolerance && - vtkm::Abs(static_cast(f_delta) - d_delta) <= tolerance) - { - auto handle = - buildSampleHandle((numSamples - 1), f_start, f_end, f_delta, appendNanAndRangeColors); - return self->Map(handle, colors); - } - } - - //otherwise we need to use double space - auto handle = buildSampleHandle((numSamples - 1), r.Min, r.Max, d_delta, appendNanAndRangeColors); - return self->Map(handle, colors); -} -} - -//--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGBA& samples, - double tolerance) const -{ - if (numSamples <= 1) - { - return false; - } - samples.NumberOfSamples = numSamples; - samples.SampleRange = this->GetRange(); - return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); -} - -//--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ColorTableSamplesRGB& samples, - double tolerance) const -{ - if (numSamples <= 1) - { - return false; - } - samples.NumberOfSamples = numSamples; - samples.SampleRange = this->GetRange(); - return sampleColorTable(this, numSamples, samples.Samples, tolerance, true); -} - -//--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle& colors, - double tolerance) const -{ - if (numSamples <= 1) - { - return false; - } - return sampleColorTable(this, numSamples, colors, tolerance, false); -} - -//--------------------------------------------------------------------------- -bool ColorTable::Sample(vtkm::Int32 numSamples, - vtkm::cont::ArrayHandle& colors, - double tolerance) const -{ - if (numSamples <= 1) - { - return false; - } - return sampleColorTable(this, numSamples, colors, tolerance, false); -} } } #endif diff --git a/vtkm/rendering/Canvas.cxx b/vtkm/rendering/Canvas.cxx index 76bd096bb..8a2684b7b 100644 --- a/vtkm/rendering/Canvas.cxx +++ b/vtkm/rendering/Canvas.cxx @@ -22,8 +22,6 @@ #include #include -#include - #include #include diff --git a/vtkm/rendering/Mapper.cxx b/vtkm/rendering/Mapper.cxx index 1c46bdff8..572405b4b 100644 --- a/vtkm/rendering/Mapper.cxx +++ b/vtkm/rendering/Mapper.cxx @@ -10,8 +10,6 @@ #include -#include - namespace vtkm { namespace rendering From 2e918c58dc0911b9c8a7fb0807435bb1309fa325 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 14 Sep 2020 16:39:51 -0600 Subject: [PATCH 33/51] Move ColorTable mapping to its own header We would really like to be able to include `vtkm::cont::ColorTable` in such a way that you don't have to compile device code (unless you are actually compiling functions for the device). Thus, the `Map` functions of `ColorTable` were in a special `ColorTable.hxx` that contains the "implementation" for `ColorTable`. That is confusing to many users. It is more clear to simply have `.h` headers that do a specific thing. To achieve these two goals, the `Map` functionality of `ColorTable` is separated out into its own header file. So you don't need to be using a device compiler just to use `ColorTable` (including `ColorTable.h`), but you do need to use a device compiler if mapping values to colors (including `ColorTableMap.h`). --- benchmarking/BenchmarkRayTracing.cxx | 2 - vtkm/cont/CMakeLists.txt | 2 +- vtkm/cont/ColorTable.cxx | 6 +- vtkm/cont/ColorTable.h | 120 -------------- vtkm/cont/ColorTable.hxx | 158 ------------------ vtkm/cont/ColorTableMap.h | 226 ++++++++++++++++++++++++++ vtkm/cont/testing/TestingColorTable.h | 24 ++- vtkm/filter/FieldToColors.hxx | 86 +++------- 8 files changed, 266 insertions(+), 358 deletions(-) delete mode 100644 vtkm/cont/ColorTable.hxx create mode 100644 vtkm/cont/ColorTableMap.h diff --git a/benchmarking/BenchmarkRayTracing.cxx b/benchmarking/BenchmarkRayTracing.cxx index 1b1585984..c4534b480 100644 --- a/benchmarking/BenchmarkRayTracing.cxx +++ b/benchmarking/BenchmarkRayTracing.cxx @@ -26,8 +26,6 @@ #include -#include - #include #include #include diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index 2a50baf52..5aef733fc 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -66,6 +66,7 @@ set(headers CellSetSingleType.h CellSetStructured.h ColorTable.h + ColorTableMap.h ColorTableSamples.h CoordinateSystem.h DataSet.h @@ -125,7 +126,6 @@ set(template_sources CellSetExplicit.hxx CellSetExtrude.hxx CellSetStructured.hxx - ColorTable.hxx FieldRangeCompute.hxx FieldRangeGlobalCompute.hxx ParticleArrayCopy.hxx diff --git a/vtkm/cont/ColorTable.cxx b/vtkm/cont/ColorTable.cxx index 96fbdeaa1..e9bdf690d 100644 --- a/vtkm/cont/ColorTable.cxx +++ b/vtkm/cont/ColorTable.cxx @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -316,13 +316,13 @@ inline bool sampleColorTable(const vtkm::cont::ColorTable* self, { auto handle = buildSampleHandle((numSamples - 1), f_start, f_end, f_delta, appendNanAndRangeColors); - return self->Map(handle, colors); + return vtkm::cont::ColorTableMap(handle, *self, colors); } } //otherwise we need to use Float64 space auto handle = buildSampleHandle((numSamples - 1), r.Min, r.Max, d_delta, appendNanAndRangeColors); - return self->Map(handle, colors); + return vtkm::cont::ColorTableMap(handle, *self, colors); } } // anonymous namespace diff --git a/vtkm/cont/ColorTable.h b/vtkm/cont/ColorTable.h index 3ef59242a..eb194705f 100644 --- a/vtkm/cont/ColorTable.h +++ b/vtkm/cont/ColorTable.h @@ -532,126 +532,6 @@ public: bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr); - /// \brief Sample each value through an intermediate lookup/sample table to generate RGBA colors - /// - /// Each value in \c values is binned based on its value in relationship to the range - /// of the color table and will use the color value at that bin from the \c samples. - /// To generate the lookup table use \c Sample . - /// - /// Here is a simple example. - /// \code{.cpp} - /// - /// vtkm::cont::ColorTableSamplesRGBA samples; - /// vtkm::cont::ColorTable table("black-body radiation"); - /// table.Sample(256, samples); - /// vtkm::cont::ArrayHandle colors; - /// table.Map(input, samples, colors); - /// - /// \endcode - template - inline bool Map(const vtkm::cont::ArrayHandle& values, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Sample each value through an intermediate lookup/sample table to generate RGB colors - /// - /// Each value in \c values is binned based on its value in relationship to the range - /// of the color table and will use the color value at that bin from the \c samples. - /// To generate the lookup table use \c Sample . - /// - /// Here is a simple example. - /// \code{.cpp} - /// - /// vtkm::cont::ColorTableSamplesRGB samples; - /// vtkm::cont::ColorTable table("black-body radiation"); - /// table.Sample(256, samples); - /// vtkm::cont::ArrayHandle colors; - /// table.Map(input, samples, colors); - /// - /// \endcode - template - inline bool Map(const vtkm::cont::ArrayHandle& values, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Use magnitude of a vector with a sample table to generate RGBA colors - /// - template - inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Use magnitude of a vector with a sample table to generate RGB colors - /// - template - inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Use a single component of a vector with a sample table to generate RGBA colors - /// - template - inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Use a single component of a vector with a sample table to generate RGB colors - /// - template - inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle& rgbOut) const; - - - /// \brief Interpolate each value through the color table to generate RGBA colors - /// - /// Each value in \c values will be sampled through the entire color table - /// to determine a color. - /// - /// Note: This is more costly than using Sample/Map with the generated intermediate lookup table - template - inline bool Map(const vtkm::cont::ArrayHandle& values, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Interpolate each value through the color table to generate RGB colors - /// - /// Each value in \c values will be sampled through the entire color table - /// to determine a color. - /// - /// Note: This is more costly than using Sample/Map with the generated intermediate lookup table - template - inline bool Map(const vtkm::cont::ArrayHandle& values, - vtkm::cont::ArrayHandle& rgbOut) const; - - /// \brief Use magnitude of a vector to generate RGBA colors - /// - template - inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Use magnitude of a vector to generate RGB colors - /// - template - inline bool MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - vtkm::cont::ArrayHandle& rgbOut) const; - - /// \brief Use a single component of a vector to generate RGBA colors - /// - template - inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - vtkm::cont::ArrayHandle& rgbaOut) const; - - /// \brief Use a single component of a vector to generate RGB colors - /// - template - inline bool MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - vtkm::cont::ArrayHandle& rgbOut) const; - - /// \brief generate RGB colors using regular spaced samples along the range. /// /// Will use the current range of the color table to generate evenly spaced diff --git a/vtkm/cont/ColorTable.hxx b/vtkm/cont/ColorTable.hxx deleted file mode 100644 index 0f8f02ed0..000000000 --- a/vtkm/cont/ColorTable.hxx +++ /dev/null @@ -1,158 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ -#ifndef vtk_m_cont_ColorTable_hxx -#define vtk_m_cont_ColorTable_hxx - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -namespace vtkm -{ -namespace cont -{ - -//--------------------------------------------------------------------------- -template -bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle& rgbaOut) const -{ - if (samples.NumberOfSamples <= 0) - { - return false; - } - vtkm::worklet::colorconversion::LookupTable lookupTable(samples); - vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); - invoke(lookupTable, values, samples.Samples, rgbaOut); - return true; -} -//--------------------------------------------------------------------------- -template -bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle& rgbOut) const -{ - if (samples.NumberOfSamples <= 0) - { - return false; - } - vtkm::worklet::colorconversion::LookupTable lookupTable(samples); - vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); - invoke(lookupTable, values, samples.Samples, rgbOut); - return true; -} -//--------------------------------------------------------------------------- -template -bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle& rgbaOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map( - vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbaOut); -} - -//--------------------------------------------------------------------------- -template -bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle& rgbOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map( - vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbOut); -} -//--------------------------------------------------------------------------- -template -bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - const vtkm::cont::ColorTableSamplesRGBA& samples, - vtkm::cont::ArrayHandle& rgbaOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map( - vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbaOut); -} -//--------------------------------------------------------------------------- -template -bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - const vtkm::cont::ColorTableSamplesRGB& samples, - vtkm::cont::ArrayHandle& rgbOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map( - vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbOut); -} - -//--------------------------------------------------------------------------- -template -bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, - vtkm::cont::ArrayHandle& rgbaOut) const -{ - vtkm::cont::Invoker invoke; - invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, *this, rgbaOut); - return true; -} -//--------------------------------------------------------------------------- -template -bool ColorTable::Map(const vtkm::cont::ArrayHandle& values, - vtkm::cont::ArrayHandle& rgbOut) const -{ - vtkm::cont::Invoker invoke; - invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, *this, rgbOut); - return true; -} -//--------------------------------------------------------------------------- -template -bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - vtkm::cont::ArrayHandle& rgbaOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map(vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), rgbaOut); -} -//--------------------------------------------------------------------------- -template -bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle, S>& values, - vtkm::cont::ArrayHandle& rgbOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map(vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), rgbOut); -} -//--------------------------------------------------------------------------- -template -bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - vtkm::cont::ArrayHandle& rgbaOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbaOut); -} -//--------------------------------------------------------------------------- -template -bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle, S>& values, - vtkm::IdComponent comp, - vtkm::cont::ArrayHandle& rgbOut) const -{ - using namespace vtkm::worklet::colorconversion; - return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbOut); -} -} -} -#endif diff --git a/vtkm/cont/ColorTableMap.h b/vtkm/cont/ColorTableMap.h new file mode 100644 index 000000000..0800a9868 --- /dev/null +++ b/vtkm/cont/ColorTableMap.h @@ -0,0 +1,226 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#ifndef vtk_m_cont_ColorTableMap_h +#define vtk_m_cont_ColorTableMap_h + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace vtkm +{ +namespace cont +{ + +/// \brief Sample each value through an intermediate lookup/sample table to generate RGBA colors +/// +/// Each value in \c values is binned based on its value in relationship to the range +/// of the color table and will use the color value at that bin from the \c samples. +/// To generate the lookup table use \c Sample . +/// +/// Here is a simple example. +/// \code{.cpp} +/// +/// vtkm::cont::ColorTableSamplesRGBA samples; +/// vtkm::cont::ColorTable table("black-body radiation"); +/// table.Sample(256, samples); +/// vtkm::cont::ArrayHandle colors; +/// vtkm::cont::ColorTableMap(input, samples, colors); +/// +/// \endcode +template +bool ColorTableMap(const vtkm::cont::ArrayHandle& values, + const vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::cont::ArrayHandle& rgbaOut) +{ + if (samples.NumberOfSamples <= 0) + { + return false; + } + vtkm::worklet::colorconversion::LookupTable lookupTable(samples); + vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); + invoke(lookupTable, values, samples.Samples, rgbaOut); + return true; +} + +/// \brief Sample each value through an intermediate lookup/sample table to generate RGB colors +/// +/// Each value in \c values is binned based on its value in relationship to the range +/// of the color table and will use the color value at that bin from the \c samples. +/// To generate the lookup table use \c Sample . +/// +/// Here is a simple example. +/// \code{.cpp} +/// +/// vtkm::cont::ColorTableSamplesRGB samples; +/// vtkm::cont::ColorTable table("black-body radiation"); +/// table.Sample(256, samples); +/// vtkm::cont::ArrayHandle colors; +/// vtkm::cont::ColorTableMap(input, samples, colors); +/// +/// \endcode +template +bool ColorTableMap(const vtkm::cont::ArrayHandle& values, + const vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::cont::ArrayHandle& rgbOut) +{ + if (samples.NumberOfSamples <= 0) + { + return false; + } + vtkm::worklet::colorconversion::LookupTable lookupTable(samples); + vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{}); + invoke(lookupTable, values, samples.Samples, rgbOut); + return true; +} + +/// \brief Use magnitude of a vector with a sample table to generate RGBA colors +/// +template +bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + const vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::cont::ArrayHandle& rgbaOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbaOut); +} + +/// \brief Use magnitude of a vector with a sample table to generate RGB colors +/// +template +bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + const vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::cont::ArrayHandle& rgbOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbOut); +} + +/// \brief Use a single component of a vector with a sample table to generate RGBA colors +/// +template +bool ColorTableMapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + const vtkm::cont::ColorTableSamplesRGBA& samples, + vtkm::cont::ArrayHandle& rgbaOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbaOut); +} + +/// \brief Use a single component of a vector with a sample table to generate RGB colors +/// +template +bool ColorTableMapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + const vtkm::cont::ColorTableSamplesRGB& samples, + vtkm::cont::ArrayHandle& rgbOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbOut); +} + +/// \brief Interpolate each value through the color table to generate RGBA colors +/// +/// Each value in \c values will be sampled through the entire color table +/// to determine a color. +/// +/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table +template +bool ColorTableMap(const vtkm::cont::ArrayHandle& values, + const vtkm::cont::ColorTable& table, + vtkm::cont::ArrayHandle& rgbaOut) +{ + vtkm::cont::Invoker invoke; + invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, table, rgbaOut); + return true; +} + +/// \brief Interpolate each value through the color table to generate RGB colors +/// +/// Each value in \c values will be sampled through the entire color table +/// to determine a color. +/// +/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table +template +bool ColorTableMap(const vtkm::cont::ArrayHandle& values, + const vtkm::cont::ColorTable& table, + vtkm::cont::ArrayHandle& rgbOut) +{ + vtkm::cont::Invoker invoke; + invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, table, rgbOut); + return true; +} + +/// \brief Use magnitude of a vector to generate RGBA colors +/// +template +bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + const vtkm::cont::ColorTable& table, + vtkm::cont::ArrayHandle& rgbaOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), table, rgbaOut); +} + +/// \brief Use magnitude of a vector to generate RGB colors +/// +template +bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle, S>& values, + const vtkm::cont::ColorTable& table, + vtkm::cont::ArrayHandle& rgbOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), table, rgbOut); +} + +/// \brief Use a single component of a vector to generate RGBA colors +/// +template +bool ColorTableMapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + const vtkm::cont::ColorTable& table, + vtkm::cont::ArrayHandle& rgbaOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), table, rgbaOut); +} + +/// \brief Use a single component of a vector to generate RGB colors +/// +template +bool ColorTableMapComponent(const vtkm::cont::ArrayHandle, S>& values, + vtkm::IdComponent comp, + const vtkm::cont::ColorTable& table, + vtkm::cont::ArrayHandle& rgbOut) +{ + using namespace vtkm::worklet::colorconversion; + return vtkm::cont::ColorTableMap( + vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), table, rgbOut); +} +} +} +#endif // vtk_m_cont_ColorTableMap_h diff --git a/vtkm/cont/testing/TestingColorTable.h b/vtkm/cont/testing/TestingColorTable.h index bf99edc73..89d1d1116 100644 --- a/vtkm/cont/testing/TestingColorTable.h +++ b/vtkm/cont/testing/TestingColorTable.h @@ -12,15 +12,13 @@ #include #include +#include #include #include // Required for implementation of ArrayRangeCompute for "odd" arrays #include -// Required for implementation of ColorTable -#include - #include #include @@ -180,7 +178,7 @@ public: auto field = vtkm::cont::make_ArrayHandle({ -1, 0, 1, 2 }); vtkm::cont::ArrayHandle colors; - const bool ran = table.Map(field, colors); + const bool ran = vtkm::cont::ColorTableMap(field, table, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); //verify that we clamp the values to the expected range @@ -203,7 +201,7 @@ public: auto field = vtkm::cont::make_ArrayHandle({ -2, -1, 2, 3 }); vtkm::cont::ArrayHandle colors; - const bool ran = table.Map(field, colors); + const bool ran = vtkm::cont::ColorTableMap(field, table, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); //verify that both the above and below range colors are used, @@ -215,7 +213,7 @@ public: //verify that we can specify custom above and below range colors table.SetAboveRangeColor(vtkm::Vec{ 1.0f, 0.0f, 0.0f }); //red table.SetBelowRangeColor(vtkm::Vec{ 0.0f, 0.0f, 1.0f }); //green - const bool ran2 = table.Map(field, colors); + const bool ran2 = vtkm::cont::ColorTableMap(field, table, colors); VTKM_TEST_ASSERT(ran2, "color table failed to execute"); CheckColors(colors, { { 0, 0, 255 }, { 0, 255, 0 }, { 255, 0, 255 }, { 255, 0, 0 } }); } @@ -248,7 +246,7 @@ public: auto field = vtkm::cont::make_ArrayHandle({ 0, 10, 20, 30, 40, 50 }); vtkm::cont::ArrayHandle colors; - const bool ran = newTable.Map(field, colors); + const bool ran = vtkm::cont::ColorTableMap(field, newTable, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); //values confirmed with ParaView 5.4 @@ -280,7 +278,7 @@ public: vtkm::cont::ArrayHandle colors; auto field = vtkm::cont::make_ArrayHandle({ 10.0f, -5.0f, -15.0f }); - const bool ran = table.Map(field, colors); + const bool ran = vtkm::cont::ColorTableMap(field, table, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); CheckColors(colors, { { 0, 0, 128 }, { 0, 128, 255 }, { 128, 255, 255 } }); @@ -315,7 +313,7 @@ public: vtkm::cont::ArrayHandle colors; auto field = vtkm::cont::make_ArrayHandle({ 0, 10, 20, 30, 40, 50 }); - const bool ran = table.Map(field, colors); + const bool ran = vtkm::cont::ColorTableMap(field, table, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); //values confirmed with ParaView 5.4 @@ -356,7 +354,7 @@ public: vtkm::cont::ArrayHandle colors; auto field = vtkm::cont::make_ArrayHandle({ 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f }); - const bool ran = table.Map(field, colors); + const bool ran = vtkm::cont::ColorTableMap(field, table, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); //values confirmed with ParaView 5.4 @@ -371,7 +369,7 @@ public: std::cout << " Change Color Space" << std::endl; vtkm::cont::ArrayHandle colors_rgb; table.SetColorSpace(vtkm::ColorSpace::RGB); - table.Map(field, colors_rgb); + vtkm::cont::ColorTableMap(field, table, colors_rgb); CheckColors(colors_rgb, { { 0, 0, 255 }, @@ -411,7 +409,7 @@ public: vtkm::cont::ArrayHandle colors; auto field = vtkm::cont::make_ArrayHandle({ 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f }); - const bool ran = table.Map(field, colors); + const bool ran = vtkm::cont::ColorTableMap(field, table, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); //values confirmed with ParaView 5.4 @@ -480,7 +478,7 @@ public: vtkm::cont::ArrayHandle colors; auto field = vtkm::cont::make_ArrayHandle({ -1, 0, 10, 20, 30, 40, 50, 60 }); - const bool ran = table.Map(field, samples, colors); + const bool ran = vtkm::cont::ColorTableMap(field, samples, colors); VTKM_TEST_ASSERT(ran, "color table failed to execute"); //values confirmed with ParaView 5.4 diff --git a/vtkm/filter/FieldToColors.hxx b/vtkm/filter/FieldToColors.hxx index b3f6254d6..e93ad765e 100644 --- a/vtkm/filter/FieldToColors.hxx +++ b/vtkm/filter/FieldToColors.hxx @@ -12,7 +12,7 @@ #define vtk_m_filter_FieldToColors_hxx #include -#include +#include #include namespace vtkm @@ -34,74 +34,68 @@ struct ComponentInputMode } template -inline bool execute(const vtkm::cont::ColorTable& table, - ScalarInputMode, +inline bool execute(ScalarInputMode, int, const T& input, const S& samples, U& output, vtkm::VecTraitsTagSingleComponent) { - return table.Map(input, samples, output); + return vtkm::cont::ColorTableMap(input, samples, output); } template -inline bool execute(const vtkm::cont::ColorTable& table, - MagnitudeInputMode, +inline bool execute(MagnitudeInputMode, int, const T& input, const S& samples, U& output, vtkm::VecTraitsTagMultipleComponents) { - return table.MapMagnitude(input, samples, output); + return vtkm::cont::ColorTableMapMagnitude(input, samples, output); } template -inline bool execute(const vtkm::cont::ColorTable& table, - ComponentInputMode, +inline bool execute(ComponentInputMode, int comp, const T& input, const S& samples, U& output, vtkm::VecTraitsTagMultipleComponents) { - return table.MapComponent(input, comp, samples, output); + return vtkm::cont::ColorTableMapComponent(input, comp, samples, output); } //error cases template -inline bool execute(const vtkm::cont::ColorTable& table, - ScalarInputMode, +inline bool execute(ScalarInputMode, int, const T& input, const S& samples, U& output, vtkm::VecTraitsTagMultipleComponents) { //vector input in scalar mode so do magnitude - return table.MapMagnitude(input, samples, output); + return vtkm::cont::ColorTableMapMagnitude(input, samples, output); } template -inline bool execute(const vtkm::cont::ColorTable& table, - MagnitudeInputMode, +inline bool execute(MagnitudeInputMode, int, const T& input, const S& samples, U& output, vtkm::VecTraitsTagSingleComponent) { //is a scalar array so ignore Magnitude mode - return table.Map(input, samples, output); + return vtkm::cont::ColorTableMap(input, samples, output); } template -inline bool execute(const vtkm::cont::ColorTable& table, - ComponentInputMode, +inline bool execute(ComponentInputMode, int, const T& input, const S& samples, U& output, vtkm::VecTraitsTagSingleComponent) { //is a scalar array so ignore COMPONENT mode - return table.Map(input, samples, output); + return vtkm::cont::ColorTableMap(input, samples, output); } @@ -167,35 +161,20 @@ inline VTKM_CONT vtkm::cont::DataSet FieldToColors::DoExecute( { case SCALAR: { - ran = execute(this->Table, - ScalarInputMode{}, - this->Component, - inField, - this->SamplesRGBA, - output, - IsVec{}); + ran = + execute(ScalarInputMode{}, this->Component, inField, this->SamplesRGBA, output, IsVec{}); break; } case MAGNITUDE: { - ran = execute(this->Table, - MagnitudeInputMode{}, - this->Component, - inField, - this->SamplesRGBA, - output, - IsVec{}); + ran = execute( + MagnitudeInputMode{}, this->Component, inField, this->SamplesRGBA, output, IsVec{}); break; } case COMPONENT: { - ran = execute(this->Table, - ComponentInputMode{}, - this->Component, - inField, - this->SamplesRGBA, - output, - IsVec{}); + ran = execute( + ComponentInputMode{}, this->Component, inField, this->SamplesRGBA, output, IsVec{}); break; } } @@ -215,35 +194,20 @@ inline VTKM_CONT vtkm::cont::DataSet FieldToColors::DoExecute( { case SCALAR: { - ran = execute(this->Table, - ScalarInputMode{}, - this->Component, - inField, - this->SamplesRGB, - output, - IsVec{}); + ran = + execute(ScalarInputMode{}, this->Component, inField, this->SamplesRGB, output, IsVec{}); break; } case MAGNITUDE: { - ran = execute(this->Table, - MagnitudeInputMode{}, - this->Component, - inField, - this->SamplesRGB, - output, - IsVec{}); + ran = execute( + MagnitudeInputMode{}, this->Component, inField, this->SamplesRGB, output, IsVec{}); break; } case COMPONENT: { - ran = execute(this->Table, - ComponentInputMode{}, - this->Component, - inField, - this->SamplesRGB, - output, - IsVec{}); + ran = execute( + ComponentInputMode{}, this->Component, inField, this->SamplesRGB, output, IsVec{}); break; } } From 991f7a85ad3f66e8bb4a7150b2b7050558932f93 Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Tue, 15 Sep 2020 09:11:00 -0700 Subject: [PATCH 34/51] Refactor mesh classes: switch from row/col/slice to vtkm::Id2/Id3 --- .../contour_tree_augmented/ContourTreeApp.cxx | 60 ++-- vtkm/cont/testing/MakeTestDataSet.h | 62 +++- vtkm/filter/ContourTreeUniformAugmented.hxx | 25 +- ...tTestContourTreeUniformAugmentedFilter.cxx | 245 +++++++++++++-- vtkm/worklet/ContourTreeUniformAugmented.h | 41 +-- .../contourtree_augmented/CMakeLists.txt | 6 +- .../contourtree_augmented/ContourTreeMaker.h | 28 +- ...Mesh_DEM_Triangulation.h => DataSetMesh.h} | 292 +++++++---------- .../worklet/contourtree_augmented/MergeTree.h | 15 +- .../contourtree_augmented/MeshExtrema.h | 2 +- vtkm/worklet/contourtree_augmented/Types.h | 35 +-- .../ComputeRegularStructure_LocateSuperarcs.h | 9 +- .../CMakeLists.txt | 0 .../{mesh_dem => data_set_mesh}/IdRelabeler.h | 48 ++- .../MeshStructure2D.h | 31 +- .../MeshStructure3D.h | 43 ++- .../SimulatedSimplicityComperator.h | 0 .../{mesh_dem => data_set_mesh}/SortIndices.h | 4 +- .../mesh_boundary/MeshBoundary3D.h | 154 --------- .../CMakeLists.txt | 6 +- .../ContourTreeMesh.h | 170 ++++++---- .../DataSetMeshTriangulation2DFreudenthal.h} | 64 ++-- .../DataSetMeshTriangulation3DFreudenthal.h} | 63 ++-- ...DataSetMeshTriangulation3DMarchingCubes.h} | 70 ++--- .../MeshStructureContourTreeMesh.h | 0 .../MeshStructureFreudenthal2D.h | 47 ++- .../MeshStructureFreudenthal3D.h | 49 ++- .../MeshStructureMarchingCubes.h | 169 +++++----- .../contourtreemesh/ArcComparator.h | 0 .../contourtreemesh/CMakeLists.txt | 0 ...ombinedOtherStartIndexNNeighboursWorklet.h | 0 ...mbinedSimulatedSimplicityIndexComparator.h | 2 +- .../contourtreemesh/CombinedVector.h | 0 .../CombinedVectorDifferentFromNext.h | 2 +- .../CompressNeighboursWorklet.h | 0 .../ComputeMaxNeighboursWorklet.h | 0 .../contourtreemesh/FindStartIndexWorklet.h | 0 .../InitToCombinedSortOrderArraysWorklet.h | 0 .../MergeCombinedOtherStartIndexWorklet.h | 0 .../ReplaceArcNumWithToVertexWorklet.h | 0 .../contourtreemesh/SubtractAssignWorklet.h | 0 .../UpdateCombinedNeighboursWorklet.h | 0 .../freudenthal_2D/Types.h | 0 .../freudenthal_3D/Types.h | 0 .../marchingcubes_3D/Types.h | 0 .../mesh_boundary/CMakeLists.txt | 0 .../mesh_boundary/ComputeMeshBoundary2D.h | 24 +- .../mesh_boundary/ComputeMeshBoundary3D.h | 55 ++-- .../ComputeMeshBoundaryContourTreeMesh.h | 6 +- .../mesh_boundary/MeshBoundary2D.h | 94 ++++-- .../meshtypes/mesh_boundary/MeshBoundary3D.h | 295 ++++++++++++++++++ .../MeshBoundaryContourTreeMesh.h | 46 +-- .../MergeBlockFunctor.h | 15 +- .../MultiBlockContourTreeHelper.h | 15 +- .../UnitTestContourTreeUniformAugmented.cxx | 41 +-- 55 files changed, 1329 insertions(+), 1004 deletions(-) rename vtkm/worklet/contourtree_augmented/{Mesh_DEM_Triangulation.h => DataSetMesh.h} (55%) rename vtkm/worklet/contourtree_augmented/{mesh_dem => data_set_mesh}/CMakeLists.txt (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem => data_set_mesh}/IdRelabeler.h (81%) rename vtkm/worklet/contourtree_augmented/{mesh_dem => data_set_mesh}/MeshStructure2D.h (81%) rename vtkm/worklet/contourtree_augmented/{mesh_dem => data_set_mesh}/MeshStructure3D.h (77%) rename vtkm/worklet/contourtree_augmented/{mesh_dem => data_set_mesh}/SimulatedSimplicityComperator.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem => data_set_mesh}/SortIndices.h (98%) delete mode 100644 vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/CMakeLists.txt (92%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/ContourTreeMesh.h (83%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes/Freudenthal_2D_Triangulation.h => meshtypes/DataSetMeshTriangulation2DFreudenthal.h} (71%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes/Freudenthal_3D_Triangulation.h => meshtypes/DataSetMeshTriangulation3DFreudenthal.h} (73%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes/MarchingCubes_3D_Triangulation.h => meshtypes/DataSetMeshTriangulation3DMarchingCubes.h} (75%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/MeshStructureContourTreeMesh.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/MeshStructureFreudenthal2D.h (85%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/MeshStructureFreudenthal3D.h (85%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/MeshStructureMarchingCubes.h (69%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/ArcComparator.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/CMakeLists.txt (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/CombinedOtherStartIndexNNeighboursWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h (98%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/CombinedVector.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/CombinedVectorDifferentFromNext.h (98%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/CompressNeighboursWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/ComputeMaxNeighboursWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/FindStartIndexWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/InitToCombinedSortOrderArraysWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/MergeCombinedOtherStartIndexWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/ReplaceArcNumWithToVertexWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/SubtractAssignWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/contourtreemesh/UpdateCombinedNeighboursWorklet.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/freudenthal_2D/Types.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/freudenthal_3D/Types.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/marchingcubes_3D/Types.h (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/mesh_boundary/CMakeLists.txt (100%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/mesh_boundary/ComputeMeshBoundary2D.h (87%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/mesh_boundary/ComputeMeshBoundary3D.h (85%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h (96%) rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/mesh_boundary/MeshBoundary2D.h (57%) create mode 100644 vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundary3D.h rename vtkm/worklet/contourtree_augmented/{mesh_dem_meshtypes => meshtypes}/mesh_boundary/MeshBoundaryContourTreeMesh.h (80%) diff --git a/examples/contour_tree_augmented/ContourTreeApp.cxx b/examples/contour_tree_augmented/ContourTreeApp.cxx index b0a962d32..a6bf6e515 100644 --- a/examples/contour_tree_augmented/ContourTreeApp.cxx +++ b/examples/contour_tree_augmented/ContourTreeApp.cxx @@ -387,8 +387,8 @@ int main(int argc, char* argv[]) #ifdef WITH_MPI #ifdef DEBUG_PRINT // From https://www.unix.com/302983597-post2.html - char* cstr_filename = new char[15]; - snprintf(cstr_filename, sizeof(filename), "cout_%d.log", rank); + char cstr_filename[32]; + snprintf(cstr_filename, sizeof(cstr_filename), "cout_%d.log", rank); int out = open(cstr_filename, O_RDWR | O_CREAT | O_APPEND, 0600); if (-1 == out) { @@ -417,8 +417,6 @@ int main(int argc, char* argv[]) perror("cannot redirect stderr"); return 255; } - - delete[] cstr_filename; #endif #endif @@ -444,12 +442,12 @@ int main(int argc, char* argv[]) // Copy the data into the values array so we can construct a multiblock dataset // TODO All we should need to do to implement BOV support is to copy the values // in the values vector and copy the dimensions in the dims vector - vtkm::Id nRows, nCols, nSlices; - vtkm::worklet::contourtree_augmented::GetRowsColsSlices temp; - temp(inDataSet.GetCellSet(), nRows, nCols, nSlices); - dims[0] = nRows; - dims[1] = nCols; - dims[2] = nSlices; + vtkm::Id3 meshSize; + vtkm::worklet::contourtree_augmented::GetPointDimensions temp; + temp(inDataSet.GetCellSet(), meshSize); + dims[0] = meshSize[0]; + dims[1] = meshSize[1]; + dims[2] = meshSize[2]; auto tempField = inDataSet.GetField("values").GetData(); values.resize(static_cast(tempField.GetNumberOfValues())); auto tempFieldHandle = tempField.AsVirtual().ReadPortal(); @@ -515,6 +513,13 @@ int main(int argc, char* argv[]) dataReadTime = currTime - prevTime; prevTime = currTime; + // swap dims order + { + vtkm::Id temp = dims[0]; + dims[0] = dims[1]; + dims[1] = temp; + } + #ifndef WITH_MPI // We only need the inDataSet if are not using MPI otherwise we'll constructe a multi-block dataset // build the input dataset vtkm::cont::DataSetBuilderUniform dsb; @@ -522,16 +527,16 @@ int main(int argc, char* argv[]) if (nDims == 2) { vtkm::Id2 vdims; - vdims[0] = static_cast(dims[1]); - vdims[1] = static_cast(dims[0]); + vdims[0] = static_cast(dims[0]); + vdims[1] = static_cast(dims[1]); inDataSet = dsb.Create(vdims); } // 3D data else { vtkm::Id3 vdims; - vdims[0] = static_cast(dims[1]); - vdims[1] = static_cast(dims[0]); + vdims[0] = static_cast(dims[0]); + vdims[1] = static_cast(dims[1]); vdims[2] = static_cast(dims[2]); inDataSet = dsb.Create(vdims); } @@ -594,8 +599,8 @@ int main(int argc, char* argv[]) { VTKM_LOG_IF_S(vtkm::cont::LogLevel::Error, rank == 0, - "Number of ranks to large for data. Use " << lastDimSize / 2 - << "or fewer ranks"); + "Number of ranks too large for data. Use " << lastDimSize / 2 + << "or fewer ranks"); MPI_Finalize(); return EXIT_FAILURE; } @@ -629,8 +634,8 @@ int main(int argc, char* argv[]) if (nDims == 2) { vtkm::Id2 vdims; - vdims[0] = static_cast(currBlockSize); - vdims[1] = static_cast(dims[0]); + vdims[0] = static_cast(dims[0]); + vdims[1] = static_cast(currBlockSize); vtkm::Vec origin(0, blockIndex * blockSize); vtkm::Vec spacing(1, 1); ds = dsb.Create(vdims, origin, spacing); @@ -645,8 +650,8 @@ int main(int argc, char* argv[]) else { vtkm::Id3 vdims; - vdims[0] = static_cast(dims[0]); - vdims[1] = static_cast(dims[1]); + vdims[0] = static_cast(dims[1]); + vdims[1] = static_cast(dims[0]); vdims[2] = static_cast(currBlockSize); vtkm::Vec origin(0, 0, (blockIndex * blockSize)); vtkm::Vec spacing(1, 1, 1); @@ -690,6 +695,21 @@ int main(int argc, char* argv[]) vtkm::Float64 computeContourTreeTime = currTime - prevTime; prevTime = currTime; +#ifdef WITH_MPI +#ifdef DEBUG_PRINT + std::cout << std::flush; + close(out); + std::cerr << std::flush; + close(err); + + dup2(save_out, fileno(stdout)); + dup2(save_err, fileno(stderr)); + + close(save_out); + close(save_err); +#endif +#endif + //////////////////////////////////////////// // Compute the branch decomposition //////////////////////////////////////////// diff --git a/vtkm/cont/testing/MakeTestDataSet.h b/vtkm/cont/testing/MakeTestDataSet.h index 34db8abf6..505a789f3 100644 --- a/vtkm/cont/testing/MakeTestDataSet.h +++ b/vtkm/cont/testing/MakeTestDataSet.h @@ -43,12 +43,14 @@ public: vtkm::cont::DataSet Make2DUniformDataSet0(); vtkm::cont::DataSet Make2DUniformDataSet1(); vtkm::cont::DataSet Make2DUniformDataSet2(); + vtkm::cont::DataSet Make2DUniformDataSet3(); // 3D uniform datasets. vtkm::cont::DataSet Make3DUniformDataSet0(); vtkm::cont::DataSet Make3DUniformDataSet1(); vtkm::cont::DataSet Make3DUniformDataSet2(); vtkm::cont::DataSet Make3DUniformDataSet3(const vtkm::Id3 dims = vtkm::Id3(10)); + vtkm::cont::DataSet Make3DUniformDataSet4(); vtkm::cont::DataSet Make3DRegularDataSet0(); vtkm::cont::DataSet Make3DRegularDataSet1(); @@ -177,7 +179,7 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet0() return dataSet; } -//Make a simple 2D, 16 cell uniform dataset. +//Make a simple 2D, 16 cell uniform dataset (5x5.txt) inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet1() { vtkm::cont::DataSetBuilderUniform dsb; @@ -233,6 +235,29 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet2() return dataSet; } + +//Make a simple 2D, 56 cell uniform dataset. (8x9test.txt) +inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet3() +{ + vtkm::cont::DataSetBuilderUniform dsb; + constexpr vtkm::Id2 dimensions(9, 8); + vtkm::cont::DataSet dataSet = dsb.Create(dimensions); + + constexpr vtkm::Id nVerts = 72; + constexpr vtkm::Float32 pointvar[nVerts] = { + 29.0f, 37.0f, 39.0f, 70.0f, 74.0f, 84.0f, 38.0f, 36.0f, 26.0f, 27.0f, 100.0f, 49.0f, + 72.0f, 85.0f, 89.0f, 83.0f, 28.0f, 24.0f, 25.0f, 47.0f, 50.0f, 73.0f, 86.0f, 90.0f, + 71.0f, 82.0f, 22.0f, 23.0f, 75.0f, 79.0f, 48.0f, 69.0f, 87.0f, 88.0f, 81.0f, 18.0f, + 19.0f, 76.0f, 80.0f, 78.0f, 46.0f, 68.0f, 67.0f, 40.0f, 16.0f, 17.0f, 41.0f, 77.0f, + 45.0f, 35.0f, 20.0f, 21.0f, 32.0f, 15.0f, 13.0f, 42.0f, 43.0f, 44.0f, 34.0f, 33.0f, + 31.0f, 30.0f, 14.0f, 12.0f, 11.0f, 10.0f, 9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 0.0f + }; + + dataSet.AddPointField("pointvar", pointvar, nVerts); + + return dataSet; +} + //Make a simple 3D, 4 cell uniform dataset. inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet0() { @@ -254,7 +279,7 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet0() return dataSet; } -//Make a simple 3D, 64 cell uniform dataset. +//Make a simple 3D, 64 cell uniform dataset. (5b 5x5x5) inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet1() { vtkm::cont::DataSetBuilderUniform dsb; @@ -372,6 +397,39 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet3(const vtkm::Id return dataSet; } +//Make a simple 3D, 120 cell uniform dataset. (This is the data set from +//Make3DUniformDataSet1 upsampled from 5x5x to 5x6x7.) +inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet4() +{ + vtkm::cont::DataSetBuilderUniform dsb; + constexpr vtkm::Id3 dimensions(5, 6, 7); + vtkm::cont::DataSet dataSet = dsb.Create(dimensions); + + constexpr vtkm::Id nVerts = 210; + constexpr vtkm::Float32 pointvar[nVerts] = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.53f, 0.48f, 0.45f, + 0.0f, 0.0f, 0.64f, 0.56f, 0.61f, 0.0f, 0.0f, 0.61f, 0.56f, 0.64f, 0.0f, 0.0f, 0.45f, + 0.48f, 0.53f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.73f, 0.61f, 0.63f, 0.0f, 0.0f, 0.85f, 0.66f, 0.78f, 0.0f, 0.0f, 0.80f, 0.64f, + 0.83f, 0.0f, 0.0f, 0.61f, 0.59f, 0.71f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.60f, 0.40f, 0.53f, 0.0f, 0.0f, 0.63f, 0.29f, 0.53f, + 0.0f, 0.0f, 0.57f, 0.25f, 0.55f, 0.0f, 0.0f, 0.48f, 0.32f, 0.56f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.72f, 0.60f, 0.61f, 0.0f, + 0.0f, 0.84f, 0.64f, 0.76f, 0.0f, 0.0f, 0.78f, 0.62f, 0.81f, 0.0f, 0.0f, 0.60f, 0.57f, + 0.70f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.52f, 0.46f, 0.44f, 0.0f, 0.0f, 0.63f, 0.54f, 0.59f, 0.0f, 0.0f, 0.59f, 0.54f, 0.63f, + 0.0f, 0.0f, 0.44f, 0.46f, 0.52f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f + }; + dataSet.AddPointField("pointvar", pointvar, nVerts); + + return dataSet; +} + inline vtkm::cont::DataSet MakeTestDataSet::Make2DRectilinearDataSet0() { vtkm::cont::DataSetBuilderRectilinear dsb; diff --git a/vtkm/filter/ContourTreeUniformAugmented.hxx b/vtkm/filter/ContourTreeUniformAugmented.hxx index 665f02034..d42a03291 100644 --- a/vtkm/filter/ContourTreeUniformAugmented.hxx +++ b/vtkm/filter/ContourTreeUniformAugmented.hxx @@ -57,7 +57,7 @@ #include #include -#include +#include // clang-format off VTKM_THIRDPARTY_PRE_INCLUDE @@ -161,14 +161,12 @@ vtkm::cont::DataSet ContourTreeAugmented::DoExecute( throw vtkm::cont::ErrorFilterExecution("Point field expected."); } - // Use the GetRowsColsSlices struct defined in the header to collect the nRows, nCols, and nSlices information + // Use the GetPointDimensions struct defined in the header to collect the meshSize information vtkm::worklet::ContourTreeAugmented worklet; - vtkm::Id nRows; - vtkm::Id nCols; - vtkm::Id nSlices = 1; + vtkm::Id3 meshSize; const auto& cells = input.GetCellSet(); vtkm::filter::ApplyPolicyCellSet(cells, policy, *this) - .CastAndCall(vtkm::worklet::contourtree_augmented::GetRowsColsSlices(), nRows, nCols, nSlices); + .CastAndCall(vtkm::worklet::contourtree_augmented::GetPointDimensions(), meshSize); // TODO blockIndex needs to change if we have multiple blocks per MPI rank and DoExecute is called for multiple blocks std::size_t blockIndex = 0; @@ -193,9 +191,7 @@ vtkm::cont::DataSet ContourTreeAugmented::DoExecute( MultiBlockTreeHelper ? MultiBlockTreeHelper->LocalSortOrders[blockIndex] : this->MeshSortOrder, this->NumIterations, - nRows, - nCols, - nSlices, + meshSize, this->UseMarchingCubes, compRegularStruct); @@ -319,7 +315,7 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute( // create the local data block structure localDataBlocks[bi] = new vtkm::worklet::contourtree_distributed::ContourTreeBlockData(); localDataBlocks[bi]->NumVertices = currContourTreeMesh->NumVertices; - localDataBlocks[bi]->SortOrder = currContourTreeMesh->SortOrder; + // localDataBlocks[bi]->SortOrder = currContourTreeMesh->SortOrder; localDataBlocks[bi]->SortedValue = currContourTreeMesh->SortedValues; localDataBlocks[bi]->GlobalMeshIndex = currContourTreeMesh->GlobalMeshIndex; localDataBlocks[bi]->Neighbours = currContourTreeMesh->Neighbours; @@ -411,7 +407,9 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute( // Construct the contour tree mesh from the last block vtkm::worklet::contourtree_augmented::ContourTreeMesh contourTreeMeshOut; contourTreeMeshOut.NumVertices = localDataBlocks[0]->NumVertices; - contourTreeMeshOut.SortOrder = localDataBlocks[0]->SortOrder; + // contourTreeMeshOut.SortOrder = localDataBlocks[0]->SortOrder; + contourTreeMeshOut.SortOrder = vtkm::cont::ArrayHandleIndex(contourTreeMeshOut.NumVertices); + contourTreeMeshOut.SortIndices = vtkm::cont::ArrayHandleIndex(contourTreeMeshOut.NumVertices); contourTreeMeshOut.SortedValues = localDataBlocks[0]->SortedValue; contourTreeMeshOut.GlobalMeshIndex = localDataBlocks[0]->GlobalMeshIndex; contourTreeMeshOut.Neighbours = localDataBlocks[0]->Neighbours; @@ -424,10 +422,7 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute( maxIdx[1] = maxIdx[1] - 1; maxIdx[2] = maxIdx[2] > 0 ? (maxIdx[2] - 1) : 0; auto meshBoundaryExecObj = contourTreeMeshOut.GetMeshBoundaryExecutionObject( - this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize[0], - this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize[1], - minIdx, - maxIdx); + this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize, minIdx, maxIdx); // Run the worklet to compute the final contour tree worklet.Run( contourTreeMeshOut.SortedValues, // Unused param. Provide something to keep API happy diff --git a/vtkm/filter/testing/UnitTestContourTreeUniformAugmentedFilter.cxx b/vtkm/filter/testing/UnitTestContourTreeUniformAugmentedFilter.cxx index 92c14ad7e..1bfe3ac05 100644 --- a/vtkm/filter/testing/UnitTestContourTreeUniformAugmentedFilter.cxx +++ b/vtkm/filter/testing/UnitTestContourTreeUniformAugmentedFilter.cxx @@ -78,19 +78,29 @@ private: // // Internal helper function to execute the contour tree and save repeat code in tests // + // datSets: 0 -> 5x5.txt (2D), 1 -> 8x9test.txt (2D), 2-> 5b.txt (3D) vtkm::filter::ContourTreeAugmented RunContourTree(bool useMarchingCubes, unsigned int computeRegularStructure, - unsigned int numDims = 2) const + unsigned int dataSetNo) const { // Create the input uniform cell set with values to contour vtkm::cont::DataSet dataSet; - if (numDims == 2) + switch (dataSetNo) { - dataSet = MakeTestDataSet().Make2DUniformDataSet1(); - } - else if (numDims == 3) - { - dataSet = MakeTestDataSet().Make3DUniformDataSet1(); + case 0: + dataSet = MakeTestDataSet().Make2DUniformDataSet1(); + break; + case 1: + dataSet = MakeTestDataSet().Make2DUniformDataSet3(); + break; + case 2: + dataSet = MakeTestDataSet().Make3DUniformDataSet1(); + break; + case 3: + dataSet = MakeTestDataSet().Make3DUniformDataSet4(); + break; + default: + VTKM_TEST_ASSERT(false); } vtkm::filter::ContourTreeAugmented filter(useMarchingCubes, computeRegularStructure); filter.SetActiveField("pointvar"); @@ -102,14 +112,15 @@ public: // // Create a uniform 2D structured cell set as input with values for contours // - void TestContourTree_Mesh2D_Freudenthal(unsigned int computeRegularStructure = 1) const + void TestContourTree_Mesh2D_Freudenthal_SquareExtents( + unsigned int computeRegularStructure = 1) const { std::cout << "Testing ContourTree_Augmented 2D Mesh. computeRegularStructure=" << computeRegularStructure << std::endl; vtkm::filter::ContourTreeAugmented filter = RunContourTree(false, // no marching cubes, computeRegularStructure, // compute regular structure - 2 // use 2D mesh + 0 // use 5x5.txt ); // Compute the saddle peaks to make sure the contour tree is correct @@ -148,7 +159,58 @@ public: "Wrong result for ContourTree filter"); } - void TestContourTree_Mesh3D_Freudenthal(unsigned int computeRegularStructure = 1) const + void TestContourTree_Mesh2D_Freudenthal_NonSquareExtents( + unsigned int computeRegularStructure = 1) const + { + std::cout << "Testing ContourTree_Augmented 2D Mesh. computeRegularStructure=" + << computeRegularStructure << std::endl; + vtkm::filter::ContourTreeAugmented filter = + RunContourTree(false, // no marching cubes, + computeRegularStructure, // compute regular structure + 1 // use 8x9test.txt + ); + + // Compute the saddle peaks to make sure the contour tree is correct + vtkm::worklet::contourtree_augmented::EdgePairArray saddlePeak; + vtkm::worklet::contourtree_augmented::ProcessContourTree::CollectSortedSuperarcs( + filter.GetContourTree(), filter.GetSortOrder(), saddlePeak); + + // Print the contour tree we computed + std::cout << "Computed Contour Tree" << std::endl; + vtkm::worklet::contourtree_augmented::PrintEdgePairArray(saddlePeak); + // Print the expected contour tree + std::cout << "Expected Contour Tree" << std::endl; + std::cout << " 10 20" << std::endl; + std::cout << " 20 34" << std::endl; + std::cout << " 20 38" << std::endl; + std::cout << " 20 61" << std::endl; + std::cout << " 23 34" << std::endl; + std::cout << " 24 34" << std::endl; + std::cout << " 50 61" << std::endl; + std::cout << " 61 71" << std::endl; + + VTKM_TEST_ASSERT(test_equal(saddlePeak.GetNumberOfValues(), 8), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(0), vtkm::make_Pair(10, 20)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(1), vtkm::make_Pair(20, 34)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(2), vtkm::make_Pair(20, 38)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(3), vtkm::make_Pair(20, 61)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(4), vtkm::make_Pair(23, 34)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(5), vtkm::make_Pair(24, 34)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(6), vtkm::make_Pair(50, 61)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(7), vtkm::make_Pair(61, 71)), + "Wrong result for ContourTree filter"); + } + + void TestContourTree_Mesh3D_Freudenthal_CubicExtents( + unsigned int computeRegularStructure = 1) const { std::cout << "Testing ContourTree_Augmented 3D Mesh. computeRegularStructure=" << computeRegularStructure << std::endl; @@ -157,7 +219,7 @@ public: vtkm::filter::ContourTreeAugmented filter = RunContourTree(false, // no marching cubes, computeRegularStructure, // compute regular structure - 3 // use 2D mesh + 2 // use 5b.txt (3D) mesh ); // Compute the saddle peaks to make sure the contour tree is correct @@ -203,7 +265,64 @@ public: "Wrong result for ContourTree filter"); } - void TestContourTree_Mesh3D_MarchingCubes(unsigned int computeRegularStructure = 1) const + void TestContourTree_Mesh3D_Freudenthal_NonCubicExtents( + unsigned int computeRegularStructure = 1) const + { + std::cout << "Testing ContourTree_Augmented 3D Mesh. computeRegularStructure=" + << computeRegularStructure << std::endl; + + // Execute the filter + vtkm::filter::ContourTreeAugmented filter = + RunContourTree(false, // no marching cubes, + computeRegularStructure, // compute regular structure + 3 // use 5b.txt (3D) upsampled to 5x6x7 mesh + ); + + // Compute the saddle peaks to make sure the contour tree is correct + vtkm::worklet::contourtree_augmented::EdgePairArray saddlePeak; + vtkm::worklet::contourtree_augmented::ProcessContourTree::CollectSortedSuperarcs( + filter.GetContourTree(), filter.GetSortOrder(), saddlePeak); + + // Print the contour tree we computed + std::cout << "Computed Contour Tree" << std::endl; + vtkm::worklet::contourtree_augmented::PrintEdgePairArray(saddlePeak); + // Print the expected contour tree + std::cout << "Expected Contour Tree" << std::endl; + std::cout << " 0 112" << std::endl; + std::cout << " 71 72" << std::endl; + std::cout << " 72 78" << std::endl; + std::cout << " 72 101" << std::endl; + std::cout << " 101 112" << std::endl; + std::cout << " 101 132" << std::endl; + std::cout << " 107 112" << std::endl; + std::cout << " 131 132" << std::endl; + std::cout << " 132 138" << std::endl; + + // Make sure the contour tree is correct + VTKM_TEST_ASSERT(test_equal(saddlePeak.GetNumberOfValues(), 9), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(0), vtkm::make_Pair(0, 112)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(1), vtkm::make_Pair(71, 72)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(2), vtkm::make_Pair(72, 78)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(3), vtkm::make_Pair(72, 101)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(4), vtkm::make_Pair(101, 112)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(5), vtkm::make_Pair(101, 132)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(6), vtkm::make_Pair(107, 112)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(7), vtkm::make_Pair(131, 132)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(8), vtkm::make_Pair(132, 138)), + "Wrong result for ContourTree filter"); + } + + void TestContourTree_Mesh3D_MarchingCubes_CubicExtents( + unsigned int computeRegularStructure = 1) const { std::cout << "Testing ContourTree_Augmented 3D Mesh Marching Cubes. computeRegularStructure=" << computeRegularStructure << std::endl; @@ -212,7 +331,7 @@ public: vtkm::filter::ContourTreeAugmented filter = RunContourTree(true, // no marching cubes, computeRegularStructure, // compute regular structure - 3 // use 3D mesh + 2 // use 5b.txt (3D) mesh ); // Compute the saddle peaks to make sure the contour tree is correct @@ -263,28 +382,110 @@ public: "Wrong result for ContourTree filter"); } + void TestContourTree_Mesh3D_MarchingCubes_NonCubicExtents( + unsigned int computeRegularStructure = 1) const + { + std::cout << "Testing ContourTree_Augmented 3D Mesh Marching Cubes. computeRegularStructure=" + << computeRegularStructure << std::endl; + + // Execute the filter + vtkm::filter::ContourTreeAugmented filter = + RunContourTree(true, // no marching cubes, + computeRegularStructure, // compute regular structure + 3 // use 5b.txt (3D) upsampled to 5x6x7 mesh + ); + + // Compute the saddle peaks to make sure the contour tree is correct + vtkm::worklet::contourtree_augmented::EdgePairArray saddlePeak; + vtkm::worklet::contourtree_augmented::ProcessContourTree::CollectSortedSuperarcs( + filter.GetContourTree(), filter.GetSortOrder(), saddlePeak); + + // Print the contour tree we computed + std::cout << "Computed Contour Tree" << std::endl; + vtkm::worklet::contourtree_augmented::PrintEdgePairArray(saddlePeak); + // Print the expected contour tree + std::cout << "Expected Contour Tree" << std::endl; + std::cout << " 0 203" << std::endl; + std::cout << " 71 72" << std::endl; + std::cout << " 72 78" << std::endl; + std::cout << " 72 101" << std::endl; + std::cout << " 101 112" << std::endl; + std::cout << " 101 132" << std::endl; + std::cout << " 107 112" << std::endl; + std::cout << " 112 203" << std::endl; + std::cout << " 131 132" << std::endl; + std::cout << " 132 138" << std::endl; + std::cout << " 203 209" << std::endl; + + VTKM_TEST_ASSERT(test_equal(saddlePeak.GetNumberOfValues(), 11), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(0), vtkm::make_Pair(0, 203)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(1), vtkm::make_Pair(71, 72)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(2), vtkm::make_Pair(72, 78)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(3), vtkm::make_Pair(72, 101)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(4), vtkm::make_Pair(101, 112)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(5), vtkm::make_Pair(101, 132)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(6), vtkm::make_Pair(107, 112)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(7), vtkm::make_Pair(112, 203)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(8), vtkm::make_Pair(131, 132)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(9), vtkm::make_Pair(132, 138)), + "Wrong result for ContourTree filter"); + VTKM_TEST_ASSERT(test_equal(saddlePeak.WritePortal().Get(10), vtkm::make_Pair(203, 209)), + "Wrong result for ContourTree filter"); + } + void operator()() const { // Test 2D Freudenthal with augmentation - this->TestContourTree_Mesh2D_Freudenthal(1); + this->TestContourTree_Mesh2D_Freudenthal_SquareExtents(1); // Make sure the contour tree does not change when we disable augmentation - this->TestContourTree_Mesh2D_Freudenthal(0); + this->TestContourTree_Mesh2D_Freudenthal_SquareExtents(0); // Make sure the contour tree does not change when we use boundary augmentation - this->TestContourTree_Mesh2D_Freudenthal(2); + this->TestContourTree_Mesh2D_Freudenthal_SquareExtents(2); + + // Test 2D Freudenthal with augmentation + this->TestContourTree_Mesh2D_Freudenthal_NonSquareExtents(1); + // Make sure the contour tree does not change when we disable augmentation + this->TestContourTree_Mesh2D_Freudenthal_NonSquareExtents(0); + // Make sure the contour tree does not change when we use boundary augmentation + this->TestContourTree_Mesh2D_Freudenthal_NonSquareExtents(2); // Test 3D Freudenthal with augmentation - this->TestContourTree_Mesh3D_Freudenthal(1); + this->TestContourTree_Mesh3D_Freudenthal_CubicExtents(1); // Make sure the contour tree does not change when we disable augmentation - this->TestContourTree_Mesh3D_Freudenthal(0); + this->TestContourTree_Mesh3D_Freudenthal_CubicExtents(0); // Make sure the contour tree does not change when we use boundary augmentation - this->TestContourTree_Mesh3D_Freudenthal(2); + this->TestContourTree_Mesh3D_Freudenthal_CubicExtents(2); + + // Test 3D Freudenthal with augmentation + this->TestContourTree_Mesh3D_Freudenthal_NonCubicExtents(1); + // Make sure the contour tree does not change when we disable augmentation + this->TestContourTree_Mesh3D_Freudenthal_NonCubicExtents(0); + // Make sure the contour tree does not change when we use boundary augmentation + this->TestContourTree_Mesh3D_Freudenthal_NonCubicExtents(2); // Test 3D marching cubes with augmentation - this->TestContourTree_Mesh3D_MarchingCubes(1); + this->TestContourTree_Mesh3D_MarchingCubes_CubicExtents(1); // Make sure the contour tree does not change when we disable augmentation - this->TestContourTree_Mesh3D_MarchingCubes(0); + this->TestContourTree_Mesh3D_MarchingCubes_CubicExtents(0); // Make sure the contour tree does not change when we use boundary augmentation - this->TestContourTree_Mesh3D_MarchingCubes(2); + this->TestContourTree_Mesh3D_MarchingCubes_CubicExtents(2); + + // Test 3D marching cubes with augmentation + this->TestContourTree_Mesh3D_MarchingCubes_NonCubicExtents(1); + // Make sure the contour tree does not change when we disable augmentation + this->TestContourTree_Mesh3D_MarchingCubes_NonCubicExtents(0); + // Make sure the contour tree does not change when we use boundary augmentation + this->TestContourTree_Mesh3D_MarchingCubes_NonCubicExtents(2); } }; } diff --git a/vtkm/worklet/ContourTreeUniformAugmented.h b/vtkm/worklet/ContourTreeUniformAugmented.h index c4b2aa0a8..f5e67a0eb 100644 --- a/vtkm/worklet/ContourTreeUniformAugmented.h +++ b/vtkm/worklet/ContourTreeUniformAugmented.h @@ -71,14 +71,14 @@ #include #include #include +#include #include #include -#include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace vtkm { @@ -109,15 +109,17 @@ public: * the full regular strucuture this is not needed because all vertices * (including the boundary) will be addded to the tree anyways. */ - template - void Run(const vtkm::cont::ArrayHandle - fieldArray, // TODO: We really should not need this - contourtree_augmented::ContourTreeMesh& mesh, + template + void Run(const vtkm::cont::ArrayHandle fieldArray, + MeshType& mesh, contourtree_augmented::ContourTree& contourTree, - contourtree_augmented::IdArrayType sortOrder, + contourtree_augmented::IdArrayType& sortOrder, vtkm::Id& nIterations, unsigned int computeRegularStructure, - const contourtree_augmented::MeshBoundaryContourTreeMeshExec& meshBoundary) + const MeshBoundaryMeshExecType& meshBoundary) { RunContourTree( fieldArray, // Just a place-holder to fill the required field. Used when calling SortData on the contour tree which is a no-op @@ -157,18 +159,16 @@ public: contourtree_augmented::ContourTree& contourTree, contourtree_augmented::IdArrayType& sortOrder, vtkm::Id& nIterations, - const vtkm::Id nRows, - const vtkm::Id nCols, - const vtkm::Id nSlices = 1, + const vtkm::Id3 meshSize, bool useMarchingCubes = false, unsigned int computeRegularStructure = 1) { using namespace vtkm::worklet::contourtree_augmented; // 2D Contour Tree - if (nSlices == 1) + if (meshSize[2] == 1) { // Build the mesh and fill in the values - Mesh_DEM_Triangulation_2D_Freudenthal mesh(nRows, nCols); + DataSetMeshTriangulation2DFreudenthal mesh(vtkm::Id2{ meshSize[0], meshSize[1] }); // Run the contour tree on the mesh RunContourTree(fieldArray, contourTree, @@ -183,7 +183,7 @@ public: else if (useMarchingCubes) { // Build the mesh and fill in the values - Mesh_DEM_Triangulation_3D_MarchingCubes mesh(nRows, nCols, nSlices); + DataSetMeshTriangulation3DMarchingCubes mesh(meshSize); // Run the contour tree on the mesh RunContourTree(fieldArray, contourTree, @@ -198,7 +198,7 @@ public: else { // Build the mesh and fill in the values - Mesh_DEM_Triangulation_3D_Freudenthal mesh(nRows, nCols, nSlices); + DataSetMeshTriangulation3DFreudenthal mesh(meshSize); // Run the contour tree on the mesh RunContourTree(fieldArray, contourTree, @@ -355,7 +355,10 @@ private: // Collect the output data nIterations = treeMaker.ContourTreeResult.NumIterations; - sortOrder = mesh.SortOrder; + // Need to make a copy of sortOrder since ContourTreeMesh uses a smart array handle + // TODO: Check if we can just make sortOrder a return array with variable type or if we can make the SortOrder return optional + vtkm::cont::Algorithm::Copy(mesh.SortOrder, sortOrder); + // sortOrder = mesh.SortOrder; // ProcessContourTree::CollectSortedSuperarcs(contourTree, mesh.SortOrder, saddlePeak); // contourTree.SortedArcPrint(mesh.SortOrder); // contourTree.PrintDotSuperStructure(); diff --git a/vtkm/worklet/contourtree_augmented/CMakeLists.txt b/vtkm/worklet/contourtree_augmented/CMakeLists.txt index eeb632d86..0917dcbd2 100644 --- a/vtkm/worklet/contourtree_augmented/CMakeLists.txt +++ b/vtkm/worklet/contourtree_augmented/CMakeLists.txt @@ -13,8 +13,8 @@ set(headers ActiveGraph.h ContourTree.h ContourTreeMaker.h + DataSetMesh.h MergeTree.h - Mesh_DEM_Triangulation.h MeshExtrema.h PointerDoubling.h PrintVectors.h @@ -22,8 +22,8 @@ set(headers Types.h ) #----------------------------------------------------------------------------- -add_subdirectory(mesh_dem) -add_subdirectory(mesh_dem_meshtypes) +add_subdirectory(data_set_mesh) +add_subdirectory(meshtypes) add_subdirectory(meshextrema) add_subdirectory(activegraph) add_subdirectory(contourtreemaker) diff --git a/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h b/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h index af3b36cfa..758f5b121 100644 --- a/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h +++ b/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h @@ -58,9 +58,9 @@ // local includes #include #include +#include #include #include -#include #include #include @@ -534,20 +534,26 @@ void ContourTreeMaker::ComputeBoundaryRegularStructure( // for (indexType supernode = 0; supernode < this->ContourTreeResult.Supernodes.size(); supernode++) // superparents[this->ContourTreeResult.Supernodes[supernode]] = supernode; + IdArrayType sortOrder; // TODO/FIX: Why is this copy necessary? + vtkm::cont::Algorithm::Copy(mesh.SortOrder, sortOrder); + // Second step - for all remaining (regular) nodes, locate the superarc to which they belong contourtree_maker_inc_ns::ComputeRegularStructure_LocateSuperarcsOnBoundary locateSuperarcsOnBoundaryWorklet(this->ContourTreeResult.Hypernodes.GetNumberOfValues(), this->ContourTreeResult.Supernodes.GetNumberOfValues()); - this->Invoke(locateSuperarcsOnBoundaryWorklet, - superparents, // (input/output) - this->ContourTreeResult.WhenTransferred, // (input) - this->ContourTreeResult.Hyperparents, // (input) - this->ContourTreeResult.Hyperarcs, // (input) - this->ContourTreeResult.Hypernodes, // (input) - this->ContourTreeResult.Supernodes, // (input) - meshExtrema.Peaks, // (input) - meshExtrema.Pits, // (input) - meshBoundaryExecObj); // (input) + this->Invoke( + locateSuperarcsOnBoundaryWorklet, + superparents, // (input/output) + this->ContourTreeResult.WhenTransferred, // (input) + this->ContourTreeResult.Hyperparents, // (input) + this->ContourTreeResult.Hyperarcs, // (input) + this->ContourTreeResult.Hypernodes, // (input) + this->ContourTreeResult.Supernodes, // (input) + meshExtrema.Peaks, // (input) + meshExtrema.Pits, // (input) + sortOrder, // (input) + //mesh.SortOrder, // (input) // TODO/FIXME: Why can't I just pass this? + meshBoundaryExecObj); // (input) // We have now set the superparent correctly for each node, and need to sort them to get the correct regular arcs // DAVID "ContourTreeMaker.h" line 338 diff --git a/vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h b/vtkm/worklet/contourtree_augmented/DataSetMesh.h similarity index 55% rename from vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h rename to vtkm/worklet/contourtree_augmented/DataSetMesh.h index 340396a7b..39d929d14 100644 --- a/vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h +++ b/vtkm/worklet/contourtree_augmented/DataSetMesh.h @@ -68,10 +68,8 @@ // //============================================================================== - - -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_h +#ifndef vtk_m_worklet_contourtree_augmented_data_set_mesh_h +#define vtk_m_worklet_contourtree_augmented_data_set_mesh_h #include #include @@ -82,12 +80,11 @@ #include #include -#include -#include - +#include +#include +#include //Define namespace alias for the freudenthal types to make the code a bit more readable -namespace mesh_dem_ns = vtkm::worklet::contourtree_augmented::mesh_dem; namespace vtkm { @@ -95,17 +92,15 @@ namespace worklet { namespace contourtree_augmented { - -template -class Mesh_DEM_Triangulation +class DataSetMesh { public: - // common mesh size parameters + // common mesh size parameter, use all three dimensions ofr MeshSize with third determining if 2D or 3D + // (convention: MeshSize[2] is always >= 1, even for empty data set, so that we can detect 2D + // data as MeshSize[2] == 1) + vtkm::Id3 MeshSize; vtkm::Id NumVertices, NumLogSteps; - // Define dimensionality of the mesh - vtkm::Id NumDims; - // Array with the sorted order of the mesh vertices IdArrayType SortOrder; @@ -114,152 +109,146 @@ public: IdArrayType SortIndices; //empty constructor - Mesh_DEM_Triangulation() - : NumVertices(0) - , NumLogSteps(0) - , NumDims(2) + DataSetMesh() + : MeshSize{ 0, 0, 1 } // Always set third dimension to 1 for easy detection of 2D vs 3D + , NumVertices(0) + , NumLogSteps(1) { } + // base constructor + DataSetMesh(vtkm::Id3 meshSize) + : MeshSize{ meshSize } + , NumVertices{ meshSize[0] * meshSize[1] * meshSize[2] } + // per convention meshSize[2] == 1 for 2D + , NumLogSteps(1) + + { + // Per convention the third dimension should be 1 (even for an empty + // mesh) or higher to make it easier to check for 2D vs. 3D data) + VTKM_ASSERT(MeshSize[2] >= 1); + // TODO/FIXME: An empty mesh will likely cause a crash down the + // road anyway, so we may want to detect that case and handle + // it appropriately. + + // Compute the number of log-jumping steps (i.e. lg_2 (NumVertices)) + // this->NumLogSteps = 1; // already set in initializer list + for (vtkm::Id shifter = this->NumVertices; shifter > 0; shifter >>= 1) + this->NumLogSteps++; + } + + virtual ~DataSetMesh() {} + // Getter function for NumVertices vtkm::Id GetNumberOfVertices() const { return this->NumVertices; } - // sorts the data and initializes the sortIndex & indexReverse + // Sorts the data and initializes SortOrder & SortIndices + template void SortData(const vtkm::cont::ArrayHandle& values); + /// Routine to return the global IDs for a set of vertices + /// We here return a fancy array handle to convert values on-the-fly without requiring additional memory + /// @param[in] meshIds Array with sort Ids to be converted from local to global Ids + /// @param[in] localToGlobalIdRelabeler This parameter is the IdRelabeler + /// used to transform local to global Ids. The relabeler relies on the + /// decomposition of the global mesh which is not know by this block. + inline vtkm::cont::ArrayHandleTransform< + vtkm::cont::ArrayHandlePermutation, + mesh_dem::IdRelabeler> + GetGlobalIdsFromSortIndices(const IdArrayType& sortIds, + const mesh_dem::IdRelabeler* localToGlobalIdRelabeler) const + { // GetGlobalIDsFromSortIndices() + auto permutedSortOrder = vtkm::cont::make_ArrayHandlePermutation(sortIds, this->SortOrder); + return vtkm::cont::ArrayHandleTransform< + vtkm::cont::ArrayHandlePermutation, + mesh_dem::IdRelabeler>(permutedSortOrder, *localToGlobalIdRelabeler); + } // GetGlobalIDsFromSortIndices() + + /// Routine to return the global IDs for a set of vertices + /// We here return a fancy array handle to convert values on-the-fly without requiring additional memory + /// @param[in] meshIds Array with mesh Ids to be converted from local to global Ids + /// @param[in] localToGlobalIdRelabeler This parameter is the IdRelabeler + /// used to transform local to global Ids. The relabeler relies on the + /// decomposition of the global mesh which is not know by this block. + inline vtkm::cont::ArrayHandleTransform + GetGlobalIdsFromMeshIndices(const IdArrayType& meshIds, + const mesh_dem::IdRelabeler* localToGlobalIdRelabeler) const + { // GetGlobalIDsFromMeshIndices() + return vtkm::cont::ArrayHandleTransform( + meshIds, *localToGlobalIdRelabeler); + } // GetGlobalIDsFromMeshIndices() + //routine that dumps out the contents of the mesh void DebugPrint(const char* message, const char* fileName, long lineNum); -protected: - virtual void DebugPrintExtends() = 0; - virtual void DebugPrintValues(const vtkm::cont::ArrayHandle& values) = 0; -}; // class Mesh_DEM_Triangulation - -template -class Mesh_DEM_Triangulation_2D : public Mesh_DEM_Triangulation -{ -public: - // 2D mesh size parameters - vtkm::Id NumColumns, NumRows; - - // Maximum outdegree - static constexpr int MAX_OUTDEGREE = 3; - - // empty constructor - Mesh_DEM_Triangulation_2D() - : Mesh_DEM_Triangulation() - , NumColumns(0) - , NumRows(0) - { - this->NumDims = 2; - } - - // base constructor - Mesh_DEM_Triangulation_2D(vtkm::Id ncols, vtkm::Id nrows) - : Mesh_DEM_Triangulation() - , NumColumns(ncols) - , NumRows(nrows) - { - this->NumDims = 2; - this->NumVertices = NumRows * NumColumns; - - // compute the number of log-jumping steps (i.e. lg_2 (NumVertices)) - this->NumLogSteps = 1; - for (vtkm::Id shifter = this->NumVertices; shifter > 0; shifter >>= 1) - this->NumLogSteps++; - } - protected: virtual void DebugPrintExtends(); - virtual void DebugPrintValues(const vtkm::cont::ArrayHandle& values); -}; // class Mesh_DEM_Triangulation_2D + template + void DebugPrintValues(const vtkm::cont::ArrayHandle& values); +}; // class DataSetMesh +// Sorts the data and initialises the SortIndices & SortOrder template -class Mesh_DEM_Triangulation_3D : public Mesh_DEM_Triangulation -{ -public: - // 2D mesh size parameters - vtkm::Id NumColumns, NumRows, NumSlices; - - // Maximum outdegree - static constexpr int MAX_OUTDEGREE = 6; // True for Freudenthal and Marching Cubes - - // empty constructor - Mesh_DEM_Triangulation_3D() - : Mesh_DEM_Triangulation() - , NumColumns(0) - , NumRows(0) - , NumSlices(0) - { - this->NumDims = 3; - } - - // base constructor - Mesh_DEM_Triangulation_3D(vtkm::Id ncols, vtkm::Id nrows, vtkm::Id nslices) - : Mesh_DEM_Triangulation() - , NumColumns(ncols) - , NumRows(nrows) - , NumSlices(nslices) - { - this->NumDims = 3; - this->NumVertices = NumRows * NumColumns * NumSlices; - - // compute the number of log-jumping steps (i.e. lg_2 (NumVertices)) - this->NumLogSteps = 1; - for (vtkm::Id shifter = this->NumVertices; shifter > 0; shifter >>= 1) - this->NumLogSteps++; - } - -protected: - virtual void DebugPrintExtends(); - virtual void DebugPrintValues(const vtkm::cont::ArrayHandle& values); -}; // class Mesh_DEM_Triangulation_3D - - -// sorts the data and initialises the SortIndices & SortOrder -template -void Mesh_DEM_Triangulation::SortData( - const vtkm::cont::ArrayHandle& values) +void DataSetMesh::SortData(const vtkm::cont::ArrayHandle& values) { // Define namespace alias for mesh dem worklets namespace mesh_dem_worklets = vtkm::worklet::contourtree_augmented::mesh_dem; // Make sure that the values have the correct size - assert(values.GetNumberOfValues() == NumVertices); + VTKM_ASSERT(values.GetNumberOfValues() == this->NumVertices); + + // Make sure that we are not running on an empty mesh + VTKM_ASSERT(this->NumVertices > 0); // Just in case, make sure that everything is cleaned up - SortIndices.ReleaseResources(); - SortOrder.ReleaseResources(); + this->SortIndices.ReleaseResources(); + this->SortOrder.ReleaseResources(); // allocate memory for the sort arrays - SortOrder.Allocate(NumVertices); - SortIndices.Allocate(NumVertices); + SortOrder.Allocate(this->NumVertices); + SortIndices.Allocate(this->NumVertices); // now sort the sort order vector by the values, i.e,. initialize the SortOrder member variable - vtkm::cont::ArrayHandleIndex initVertexIds(NumVertices); // create sequence 0, 1, .. NumVertices - vtkm::cont::ArrayCopy(initVertexIds, SortOrder); + vtkm::cont::ArrayHandleIndex initVertexIds( + this->NumVertices); // create sequence 0, 1, .. NumVertices + vtkm::cont::ArrayCopy(initVertexIds, this->SortOrder); - vtkm::cont::Algorithm::Sort(SortOrder, + vtkm::cont::Algorithm::Sort(this->SortOrder, mesh_dem::SimulatedSimplicityIndexComparator(values)); // now set the index lookup, i.e., initialize the SortIndices member variable // In serial this would be // for (indexType vertex = 0; vertex < NumVertices; vertex++) // SortIndices[SortOrder[vertex]] = vertex; - mesh_dem_worklets::SortIndices sortIndicesWorklet; + data_set_mesh::SortIndices sortIndicesWorklet; vtkm::cont::Invoker invoke; - invoke(sortIndicesWorklet, SortOrder, SortIndices); + invoke(sortIndicesWorklet, this->SortOrder, this->SortIndices); // Debug print statement DebugPrint("Data Sorted", __FILE__, __LINE__); DebugPrintValues(values); } // SortData() +// Print mesh extends +void DataSetMesh::DebugPrintExtends() +{ + // For compatibility with the output of the original PPP Implementation, print size + // as NumRows, NumColumns and NumSlices (if applicable) + PrintLabel("NumRows"); + PrintIndexType(this->MeshSize[1]); + std::cout << std::endl; + PrintLabel("NumColumns"); + PrintIndexType(this->MeshSize[0]); + std::cout << std::endl; + if (MeshSize[2] > 1) + { + PrintLabel("NumSlices"); + PrintIndexType(this->MeshSize[2]); + std::cout << std::endl; + } +} // DebugPrintExtends -template -void Mesh_DEM_Triangulation::DebugPrint(const char* message, - const char* fileName, - long lineNum) +void DataSetMesh::DebugPrint(const char* message, const char* fileName, long lineNum) { // DebugPrint() #ifdef DEBUG_PRINT std::cout << "------------------------------------------------------" << std::endl; @@ -270,13 +259,13 @@ void Mesh_DEM_Triangulation::DebugPrint(const char* message, std::cout << "------------------------------------------------------" << std::endl; //DebugPrintExtents(); PrintLabel("NumVertices"); - PrintIndexType(NumVertices); + PrintIndexType(this->NumVertices); std::cout << std::endl; PrintLabel("NumLogSteps"); PrintIndexType(this->NumLogSteps); std::cout << std::endl; - PrintIndices("Sort Indices", SortIndices); - PrintIndices("Sort Order", SortOrder); + PrintIndices("Sort Indices", this->SortIndices); + PrintIndices("Sort Order", this->SortOrder); std::cout << std::endl; #else // Avoid unused parameter warning @@ -286,41 +275,13 @@ void Mesh_DEM_Triangulation::DebugPrint(const char* message, #endif } // DebugPrint() -// print mesh extends for 2D mesh template -void Mesh_DEM_Triangulation_2D::DebugPrintExtends() -{ - PrintLabel("NumRows"); - PrintIndexType(NumRows); - std::cout << std::endl; - PrintLabel("NumColumns"); - PrintIndexType(NumColumns); - std::cout << std::endl; -} // DebugPrintExtends for 2D - -// print mesh extends for 3D mesh -template -void Mesh_DEM_Triangulation_3D::DebugPrintExtends() -{ - PrintLabel("NumRows"); - PrintIndexType(NumRows); - std::cout << std::endl; - PrintLabel("NumColumns"); - PrintIndexType(NumColumns); - std::cout << std::endl; - PrintLabel("NumSlices"); - PrintIndexType(NumSlices); - std::cout << std::endl; -} - -template -void Mesh_DEM_Triangulation_2D::DebugPrintValues( - const vtkm::cont::ArrayHandle& values) +void DataSetMesh::DebugPrintValues(const vtkm::cont::ArrayHandle& values) { #ifdef DEBUG_PRINT - if (NumColumns > 0) + if (MeshSize[0] > 0) { - PrintLabelledDataBlock("Value", values, NumColumns); + PrintLabelledDataBlock("Value", values, MeshSize[0]); PrintSortedValues("Sorted Values", values, this->SortOrder); } PrintHeader(values.GetNumberOfValues()); @@ -330,28 +291,13 @@ void Mesh_DEM_Triangulation_2D::DebugPrintValues( #endif } // DebugPrintValues -template -void Mesh_DEM_Triangulation_3D::DebugPrintValues( - const vtkm::cont::ArrayHandle& values) -{ -#ifdef DEBUG_PRINT - if (NumColumns > 0) - { - PrintLabelledDataBlock("Value", values, NumColumns); - } - PrintHeader(values.GetNumberOfValues()); -#else - // Avoid unused parameter warning - (void)values; -#endif -} // DebugPrintValues - } // namespace contourtree_augmented } // worklet } // vtkm -#include // include Mesh_DEM_Triangulation_2D_Freudenthal -#include // include Mesh_DEM_Triangulation_3D_Freudenthal -#include // include Mesh_DEM_Triangulation_3D_MarchinCubes +// Include specialized mesh classes providing triangulation/connectivity information +#include +#include +#include #endif diff --git a/vtkm/worklet/contourtree_augmented/MergeTree.h b/vtkm/worklet/contourtree_augmented/MergeTree.h index 7db045cc9..8099ddf32 100644 --- a/vtkm/worklet/contourtree_augmented/MergeTree.h +++ b/vtkm/worklet/contourtree_augmented/MergeTree.h @@ -59,7 +59,7 @@ // local includes #include #include -#include +#include //VTKM includes @@ -250,16 +250,17 @@ inline void MergeTree::DebugPrintTree(const char* message, { std::cout << mesh.SortOrder.ReadPortal().Get(arc) << std::endl; } - if (mesh.NumDims == 2) - { - if ((entry % mesh.NumColumns) == (mesh.NumColumns - 1)) + if (mesh.MeshSize[2] == 1) + { // 2D Mesh + if ((entry % mesh.MeshSize[0]) == (mesh.MeshSize[0] - 1)) { std::cout << std::endl; } } - else if (mesh.NumDims == 3) - { - if ((entry % (mesh.NumColumns * mesh.NumRows)) == (mesh.NumColumns * mesh.NumRows - 1)) + else + { // 3D Mesh + if ((entry % (mesh.MeshSize[0] * mesh.MeshSize[1])) == + (mesh.MeshSize[0] * mesh.MeshSize[1] - 1)) { std::cout << std::endl; } diff --git a/vtkm/worklet/contourtree_augmented/MeshExtrema.h b/vtkm/worklet/contourtree_augmented/MeshExtrema.h index ca7c04c8d..dfcb24a95 100644 --- a/vtkm/worklet/contourtree_augmented/MeshExtrema.h +++ b/vtkm/worklet/contourtree_augmented/MeshExtrema.h @@ -65,7 +65,7 @@ #include -#include +#include namespace mesh_extrema_inc_ns = vtkm::worklet::contourtree_augmented::mesh_extrema_inc; diff --git a/vtkm/worklet/contourtree_augmented/Types.h b/vtkm/worklet/contourtree_augmented/Types.h index 65435ed92..72a859243 100644 --- a/vtkm/worklet/contourtree_augmented/Types.h +++ b/vtkm/worklet/contourtree_augmented/Types.h @@ -249,44 +249,29 @@ public: /// to determine the rows, cols, slices parameters from the /// datasets so we can call the contour tree worklet properly. /// -struct GetRowsColsSlices +struct GetPointDimensions { //@{ /// Get the number of rows, cols, and slices of a vtkm::cont::CellSetStructured /// @param[in] cells The input vtkm::cont::CellSetStructured - /// @param[out] nRows Number of rows (x) in the cell set - /// @param[out[ nCols Number of columns (y) in the cell set - /// @param[out] nSlices Number of slices (z) in the cell set - void operator()(const vtkm::cont::CellSetStructured<2>& cells, - vtkm::Id& nRows, - vtkm::Id& nCols, - vtkm::Id& nSlices) const + /// @param[out] pointDimensions mesh size (#cols, #rows #slices in old notation) with last dimension having a value of 1 for 2D data + void operator()(const vtkm::cont::CellSetStructured<2>& cells, vtkm::Id3& pointDimensions) const { - vtkm::Id2 pointDimensions = cells.GetPointDimensions(); - nRows = pointDimensions[0]; - nCols = pointDimensions[1]; - nSlices = 1; + vtkm::Id2 pointDimensions2D = cells.GetPointDimensions(); + pointDimensions[0] = pointDimensions2D[0]; + pointDimensions[1] = pointDimensions2D[1]; + pointDimensions[2] = 1; } - void operator()(const vtkm::cont::CellSetStructured<3>& cells, - vtkm::Id& nRows, - vtkm::Id& nCols, - vtkm::Id& nSlices) const + void operator()(const vtkm::cont::CellSetStructured<3>& cells, vtkm::Id3& pointDimensions) const { - vtkm::Id3 pointDimensions = cells.GetPointDimensions(); - nRows = pointDimensions[0]; - nCols = pointDimensions[1]; - nSlices = pointDimensions[2]; + pointDimensions = cells.GetPointDimensions(); } //@} /// Raise ErrorBadValue if the input cell set is not a vtkm::cont::CellSetStructured<2> or <3> template - void operator()(const T& cells, vtkm::Id& nRows, vtkm::Id& nCols, vtkm::Id& nSlices) const + void operator()(const T&, vtkm::Id3&) const { - (void)nRows; - (void)nCols; - (void)nSlices; - (void)cells; throw vtkm::cont::ErrorBadValue("Expected 2D or 3D structured cell cet! "); } }; diff --git a/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h b/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h index 5554e47fa..c32bd1b16 100644 --- a/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h +++ b/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h @@ -415,16 +415,15 @@ public: WholeArrayIn contourTreeSupernodes, // (input) WholeArrayIn meshExtremaPeaks, // (input) WholeArrayIn meshExtremaPits, // (input) + WholeArrayIn sortOrder, // (input) ExecObject meshBoundary); // (input) - typedef void ExecutionSignature(_1, InputIndex, _2, _3, _4, _5, _6, _7, _8, _9); + typedef void ExecutionSignature(_1, InputIndex, _2, _3, _4, _5, _6, _7, _8, _9, _10); using InputDomain = _1; vtkm::Id NumHypernodes; // contourTree.Hypernodes.GetNumberOfValues() vtkm::Id NumSupernodes; // contourTree.Supernodes.GetNumberOfValues() - vtkm::Id NumRows, NumColumns, NumSlices; // Mesh 2D or 3D - NumRows, NumColumns, NumSlices - // Default Constructor VTKM_EXEC_CONT ComputeRegularStructure_LocateSuperarcsOnBoundary(vtkm::Id numHypernodes, vtkm::Id numSupernodes) @@ -443,11 +442,13 @@ public: const InFieldPortalType& contourTreeSupernodesPortal, const InFieldPortalType& meshExtremaPeaksPortal, const InFieldPortalType& meshExtremaPitsPortal, + const InFieldPortalType& sortOrderPortal, const MeshBoundaryType& meshBoundary) const { // per node // if the superparent is already set, it's a supernode, so skip it. - if (NoSuchElement(contourTreeSuperparentsPortal.Get(node)) && meshBoundary.liesOnBoundary(node)) + if (NoSuchElement(contourTreeSuperparentsPortal.Get(node)) && + meshBoundary.LiesOnBoundary(sortOrderPortal.Get(node))) { // regular nodes only // we will need to prune top and bottom until one of them prunes past the node vtkm::Id top = meshExtremaPeaksPortal.Get(node); diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem/CMakeLists.txt b/vtkm/worklet/contourtree_augmented/data_set_mesh/CMakeLists.txt similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem/CMakeLists.txt rename to vtkm/worklet/contourtree_augmented/data_set_mesh/CMakeLists.txt diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem/IdRelabeler.h b/vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h similarity index 81% rename from vtkm/worklet/contourtree_augmented/mesh_dem/IdRelabeler.h rename to vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h index 8b78d3024..0dda9a077 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem/IdRelabeler.h +++ b/vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h @@ -75,57 +75,45 @@ namespace contourtree_augmented namespace mesh_dem { - +/// A utility class that converts Ids from local to global given a mesh class IdRelabeler { public: VTKM_EXEC_CONT IdRelabeler() - : InputStartRow(0) - , InputStartCol(0) - , InputStartSlice(0) - , InputNumRows(1) - , InputNumCols(1) - , OutputNumRows(1) - , OutputNumCol(1) + : LocalBlockOrigin{ 0, 0, 0 } + , LocalBlockSize{ 1, 1, 1 } + , GlobalSize{ 1, 1, 1 } { } VTKM_EXEC_CONT - IdRelabeler(vtkm::Id iSR, - vtkm::Id iSC, - vtkm::Id iSS, - vtkm::Id iNR, - vtkm::Id iNC, - vtkm::Id oNR, - vtkm::Id oNC) - : InputStartRow(iSR) - , InputStartCol(iSC) - , InputStartSlice(iSS) - , InputNumRows(iNR) - , InputNumCols(iNC) - , OutputNumRows(oNR) - , OutputNumCol(oNC) + IdRelabeler(vtkm::Id3 lBO, vtkm::Id3 lBS, vtkm::Id3 gS) + : LocalBlockOrigin(lBO) + , LocalBlockSize(lBS) + , GlobalSize(gS) { } VTKM_EXEC_CONT vtkm::Id operator()(vtkm::Id v) const { - vtkm::Id r = InputStartRow + ((v % (InputNumRows * InputNumCols)) / InputNumCols); - vtkm::Id c = InputStartCol + (v % InputNumCols); - vtkm::Id s = InputStartSlice + v / (InputNumRows * InputNumCols); + // Translate v into mesh coordinates and add offset + vtkm::Id3 pos{ LocalBlockOrigin[0] + (v % LocalBlockSize[0]), + LocalBlockOrigin[1] + + (v % (LocalBlockSize[1] * LocalBlockSize[0]) / LocalBlockSize[0]), + LocalBlockOrigin[2] + (v / (LocalBlockSize[1] * LocalBlockSize[0])) }; - return (s * OutputNumRows + r) * OutputNumCol + c; + // Translate mesh coordinates into global Id + return (pos[2] * GlobalSize[1] + pos[1]) * GlobalSize[0] + pos[0]; } private: - vtkm::Id InputStartRow, InputStartCol, InputStartSlice; - vtkm::Id InputNumRows, InputNumCols; - vtkm::Id OutputNumRows, OutputNumCol; + vtkm::Id3 LocalBlockOrigin; + vtkm::Id3 LocalBlockSize; + vtkm::Id3 GlobalSize; }; - } // namespace mesh_dem } // namespace contourtree_augmented } // namespace worklet diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure2D.h b/vtkm/worklet/contourtree_augmented/data_set_mesh/MeshStructure2D.h similarity index 81% rename from vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure2D.h rename to vtkm/worklet/contourtree_augmented/data_set_mesh/MeshStructure2D.h index 95c355377..c54bfd933 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure2D.h +++ b/vtkm/worklet/contourtree_augmented/data_set_mesh/MeshStructure2D.h @@ -50,19 +50,18 @@ // Oliver Ruebel (LBNL) //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_execution_object_mesh_2d_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_execution_object_mesh_2d_h +#ifndef vtk_m_worklet_contourtree_augmented_data_set_mesh_execution_object_mesh_2d_h +#define vtk_m_worklet_contourtree_augmented_data_set_mesh_execution_object_mesh_2d_h #include - namespace vtkm { namespace worklet { namespace contourtree_augmented { -namespace mesh_dem +namespace data_set_mesh { // Worklet for computing the sort indices from the sort order @@ -72,35 +71,31 @@ class MeshStructure2D public: VTKM_EXEC_CONT MeshStructure2D() - : NumColumns(0) - , NumRows(0) + : MeshSize{ 0, 0 } { } VTKM_EXEC_CONT - MeshStructure2D(vtkm::Id ncols, vtkm::Id nrows) - : NumColumns(ncols) - , NumRows(nrows) + MeshStructure2D(vtkm::Id2 meshSize) + : MeshSize(meshSize) { } // number of mesh vertices VTKM_EXEC_CONT - vtkm::Id GetNumberOfVertices() const { return (this->NumRows * this->NumColumns); } + vtkm::Id GetNumberOfVertices() const { return (this->MeshSize[0] * this->MeshSize[1]); } - // vertex row - integer divide by columns VTKM_EXEC - inline vtkm::Id VertexRow(vtkm::Id v) const { return v / NumColumns; } - - // verteck column -- integer modulus by columns - VTKM_EXEC - inline vtkm::Id VertexColumn(vtkm::Id v) const { return v % NumColumns; } + inline vtkm::Id2 VertexPos(vtkm::Id v) const + { + return vtkm::Id2{ v % this->MeshSize[0], v / this->MeshSize[0] }; + } //vertex ID - row * ncols + col VTKM_EXEC - inline vtkm::Id VertexId(vtkm::Id r, vtkm::Id c) const { return r * NumColumns + c; } + inline vtkm::Id VertexId(vtkm::Id2 pos) const { return pos[1] * this->MeshSize[0] + pos[0]; } - vtkm::Id NumColumns, NumRows; + vtkm::Id2 MeshSize; }; // MeshStructure2D diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure3D.h b/vtkm/worklet/contourtree_augmented/data_set_mesh/MeshStructure3D.h similarity index 77% rename from vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure3D.h rename to vtkm/worklet/contourtree_augmented/data_set_mesh/MeshStructure3D.h index c5e02f62e..18bb62fe2 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure3D.h +++ b/vtkm/worklet/contourtree_augmented/data_set_mesh/MeshStructure3D.h @@ -50,19 +50,18 @@ // Oliver Ruebel (LBNL) //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_execution_object_mesh_3d_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_execution_object_mesh_3d_h +#ifndef vtk_m_worklet_contourtree_augmented_data_set_mesh_execution_object_mesh_3d_h +#define vtk_m_worklet_contourtree_augmented_data_set_mesh_execution_object_mesh_3d_h #include - namespace vtkm { namespace worklet { namespace contourtree_augmented { -namespace mesh_dem +namespace data_set_mesh { // Worklet for computing the sort indices from the sort order @@ -72,17 +71,13 @@ class MeshStructure3D public: VTKM_EXEC_CONT MeshStructure3D() - : NumColumns(0) - , NumRows(0) - , NumSlices(0) + : MeshSize{ 0, 0, 0 } { } VTKM_EXEC_CONT - MeshStructure3D(vtkm::Id ncols, vtkm::Id nrows, vtkm::Id nslices) - : NumColumns(ncols) - , NumRows(nrows) - , NumSlices(nslices) + MeshStructure3D(vtkm::Id3 meshSize) + : MeshSize(meshSize) { } @@ -90,29 +85,27 @@ public: VTKM_EXEC_CONT vtkm::Id GetNumberOfVertices() const { - return (this->NumRows * this->NumColumns * this->NumSlices); + return (this->MeshSize[0] * this->MeshSize[1] * this->MeshSize[2]); } - // vertex row - integer modulus by (NumRows&NumColumns) and integer divide by columns VTKM_EXEC - vtkm::Id VertexRow(vtkm::Id v) const { return (v % (NumRows * NumColumns)) / NumColumns; } - - // vertex column -- integer modulus by columns - VTKM_EXEC - vtkm::Id VertexColumn(vtkm::Id v) const { return v % NumColumns; } - - // vertex slice -- integer divide by (NumRows*NumColumns) - VTKM_EXEC - vtkm::Id VertexSlice(vtkm::Id v) const { return v / (NumRows * NumColumns); } + vtkm::Id3 VertexPos(vtkm::Id v) const + { + return vtkm::Id3{ + v % this->MeshSize[0], // column + (v % (this->MeshSize[1] * this->MeshSize[0])) / this->MeshSize[0], // row + v / (this->MeshSize[1] * this->MeshSize[0]) // slice + }; + } //vertex ID - row * ncols + col VTKM_EXEC - vtkm::Id VertexId(vtkm::Id s, vtkm::Id r, vtkm::Id c) const + vtkm::Id VertexId(vtkm::Id3 pos) const { - return (s * NumRows + r) * NumColumns + c; + return (pos[2] * this->MeshSize[1] + pos[1]) * this->MeshSize[0] + pos[0]; } - vtkm::Id NumColumns, NumRows, NumSlices; + vtkm::Id3 MeshSize; }; // Mesh_DEM_2D_ExecutionObject diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem/SimulatedSimplicityComperator.h b/vtkm/worklet/contourtree_augmented/data_set_mesh/SimulatedSimplicityComperator.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem/SimulatedSimplicityComperator.h rename to vtkm/worklet/contourtree_augmented/data_set_mesh/SimulatedSimplicityComperator.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem/SortIndices.h b/vtkm/worklet/contourtree_augmented/data_set_mesh/SortIndices.h similarity index 98% rename from vtkm/worklet/contourtree_augmented/mesh_dem/SortIndices.h rename to vtkm/worklet/contourtree_augmented/data_set_mesh/SortIndices.h index d50d96fd6..02e60efff 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem/SortIndices.h +++ b/vtkm/worklet/contourtree_augmented/data_set_mesh/SortIndices.h @@ -61,7 +61,7 @@ namespace worklet { namespace contourtree_augmented { -namespace mesh_dem +namespace data_set_mesh { // Worklet for computing the sort indices from the sort order @@ -86,7 +86,7 @@ public: } }; // Mesh2D_DEM_VertexStarter -} // namespace mesh_dem_triangulation_worklets +} // namespace data_set_mesh } // namespace contourtree_augmented } // namespace worklet } // namespace vtkm diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h b/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h deleted file mode 100644 index 3be23b14e..000000000 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h +++ /dev/null @@ -1,154 +0,0 @@ -//============================================================================ -// Copyright (c) Kitware, Inc. -// All rights reserved. -// See LICENSE.txt for details. -// -// This software is distributed WITHOUT ANY WARRANTY; without even -// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -// PURPOSE. See the above copyright notice for more information. -//============================================================================ -// Copyright (c) 2018, The Regents of the University of California, through -// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals -// from the U.S. Dept. of Energy). All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// (1) Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// (2) Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// (3) Neither the name of the University of California, Lawrence Berkeley National -// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -// OF THE POSSIBILITY OF SUCH DAMAGE. -// -//============================================================================= -// -// This code is an extension of the algorithm presented in the paper: -// Parallel Peak Pruning for Scalable SMP Contour Tree Computation. -// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens. -// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization -// (LDAV), October 2016, Baltimore, Maryland. -// -// The PPP2 algorithm and software were jointly developed by -// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and -// Oliver Ruebel (LBNL) -//============================================================================== - -// This header contains a collection of classes used to describe the boundary -// of a mesh, for each main mesh type (i.e., 2D, 3D, and ContourTreeMesh). -// For each mesh type, there are two classes, the actual boundary desriptor -// class and an ExectionObject class with the PrepareForInput function that -// VTKm expects to generate the object for the execution environment. - -#ifndef vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_3d_h -#define vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_3d_h - -#include - -#include -#include - -#include - -namespace vtkm -{ -namespace worklet -{ -namespace contourtree_augmented -{ - -template -class MeshBoundary3D : public vtkm::cont::ExecutionObjectBase -{ -public: - // Sort indicies types - using SortOrderPortalType = typename IdArrayType::template ExecutionTypes::PortalConst; - - VTKM_EXEC_CONT - MeshBoundary3D() - : MeshStructure(mesh_dem::MeshStructure3D(0, 0, 0)) - { - } - - VTKM_CONT - MeshBoundary3D(vtkm::Id nrows, - vtkm::Id ncols, - vtkm::Id nslices, - const IdArrayType& sortOrder, - vtkm::cont::Token& token) - : MeshStructure(mesh_dem::MeshStructure3D(nrows, ncols, nslices)) - { - this->SortOrderPortal = sortOrder.PrepareForInput(DeviceTag(), token); - } - - VTKM_EXEC_CONT - bool liesOnBoundary(const vtkm::Id index) const - { - vtkm::Id meshSortOrderValue = this->SortOrderPortal.Get(index); - const vtkm::Id row = this->MeshStructure.VertexRow(meshSortOrderValue); - const vtkm::Id col = this->MeshStructure.VertexColumn(meshSortOrderValue); - const vtkm::Id sli = this->MeshStructure.VertexSlice(meshSortOrderValue); - return (row == 0) || (col == 0) || (sli == 0) || (row == this->MeshStructure.NumRows - 1) || - (col == this->MeshStructure.NumColumns - 1) || (sli == this->MeshStructure.NumSlices - 1); - } - -protected: - // 3D Mesh size parameters - mesh_dem::MeshStructure3D MeshStructure; - SortOrderPortalType SortOrderPortal; -}; - - -class MeshBoundary3DExec : public vtkm::cont::ExecutionObjectBase -{ -public: - VTKM_EXEC_CONT - MeshBoundary3DExec(vtkm::Id nrows, - vtkm::Id ncols, - vtkm::Id nslices, - const IdArrayType& inSortOrder) - : NumRows(nrows) - , NumColumns(ncols) - , NumSlices(nslices) - , SortOrder(inSortOrder) - { - } - - VTKM_CONT - template - MeshBoundary3D PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const - { - return MeshBoundary3D( - this->NumRows, this->NumColumns, this->NumSlices, this->SortOrder, token); - } - -protected: - // 3D Mesh size parameters - vtkm::Id NumRows; - vtkm::Id NumColumns; - vtkm::Id NumSlices; - const IdArrayType& SortOrder; -}; - - -} // namespace contourtree_augmented -} // worklet -} // vtkm - -#endif diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/CMakeLists.txt b/vtkm/worklet/contourtree_augmented/meshtypes/CMakeLists.txt similarity index 92% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/CMakeLists.txt rename to vtkm/worklet/contourtree_augmented/meshtypes/CMakeLists.txt index b65a14666..e8f8e9237 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/CMakeLists.txt +++ b/vtkm/worklet/contourtree_augmented/meshtypes/CMakeLists.txt @@ -8,9 +8,9 @@ ## PURPOSE. See the above copyright notice for more information. ##============================================================================ set(headers - Freudenthal_2D_Triangulation.h - Freudenthal_3D_Triangulation.h - MarchingCubes_3D_Triangulation.h + DataSetMeshTriangulation2DFreudenthal.h + DataSetMeshTriangulation3DFreudenthal.h + DataSetMeshTriangulation3DMarchingCubes.h ContourTreeMesh.h MeshStructureFreudenthal2D.h MeshStructureFreudenthal3D.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h b/vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h similarity index 83% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h rename to vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h index d0c6944f2..685ab9ff5 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h @@ -74,22 +74,23 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include // This is needed only as an unused default argument. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include // TODO remove should not be needed @@ -143,7 +144,7 @@ public: const vtkm::cont::ArrayHandle& values, const IdArrayType& inGlobalMeshIndex); - // Construct a ContourTreeMesh from nodes/arcs and another ContourTreeMesh (instead of a Mesh_DEM_Triangulation) + // Construct a ContourTreeMesh from nodes/arcs and another ContourTreeMesh (instead of a DataSetMesh) // nodes/arcs: From the contour tree // ContourTreeMesh: the contour tree mesh used to compute the contour tree described by nodes/arcs ContourTreeMesh(const IdArrayType& nodes, @@ -185,8 +186,8 @@ public: static const int MAX_OUTDEGREE = 20; vtkm::Id NumVertices; - // TODO we should be able to remove this one, but we need to figure out what we need to return in the worklet instead - IdArrayType SortOrder; + vtkm::cont::ArrayHandleIndex SortOrder; + vtkm::cont::ArrayHandleIndex SortIndices; vtkm::cont::ArrayHandle SortedValues; IdArrayType GlobalMeshIndex; // neighbours stores for each vertex the indices of its neighbours. For each vertex @@ -202,12 +203,14 @@ public: // the maximum number of neighbours of a vertex vtkm::Id MaxNeighbours; + // Print Contents + void PrintContent(std::ostream& outStream = std::cout) const; + // Debug print routine - void DebugPrint(const char* message, const char* fileName, long lineNum); + void DebugPrint(const char* message, const char* fileName, long lineNum) const; // Get boundary execution object - MeshBoundaryContourTreeMeshExec GetMeshBoundaryExecutionObject(vtkm::Id totalNRows, - vtkm::Id totalNCols, + MeshBoundaryContourTreeMeshExec GetMeshBoundaryExecutionObject(vtkm::Id3 globalSize, vtkm::Id3 minIdx, vtkm::Id3 maxIdx) const; @@ -216,6 +219,42 @@ public: MeshBoundaryContourTreeMeshExec* meshBoundaryExecObj //input ) const; + /// copies the global IDs for a set of sort IDs + /// notice that the sort ID is the same as the mesh ID for the ContourTreeMesh class. + /// To reduce memory usage we here use a fancy array handle rather than copy data + /// as is needed for the DataSetMesh types. + /// We here return a fancy array handle to convert values on-the-fly without requiring additional memory + /// @param[in] sortIds Array with sort Ids to be converted from local to global Ids + /// @param[in] localToGlobalIdRelabeler This parameter is here only for + /// consistency with the DataSetMesh types but is not + /// used here and as such can simply be set to nullptr + inline vtkm::cont::ArrayHandlePermutation GetGlobalIdsFromSortIndices( + const IdArrayType& sortIds, + const vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler* localToGlobalIdRelabeler = + nullptr) const + { // GetGlobalIDsFromSortIndices() + (void)localToGlobalIdRelabeler; // avoid compiler warning + return vtkm::cont::make_ArrayHandlePermutation(sortIds, this->GlobalMeshIndex); + } // GetGlobalIDsFromSortIndices() + + /// copies the global IDs for a set of mesh IDs + /// notice that the sort ID is the same as the mesh ID for the ContourTreeMesh class. + /// To reduce memory usage we here use a fancy array handle rather than copy data + /// as is needed for the DataSetMesh types. + /// We here return a fancy array handle to convert values on-the-fly without requiring additional memory + /// @param[in] meshIds Array with mesh Ids to be converted from local to global Ids + /// @param[in] localToGlobalIdRelabeler This parameter is here only for + /// consistency with the DataSetMesh types but is not + /// used here and as such can simply be set to nullptr + inline vtkm::cont::ArrayHandlePermutation GetGlobalIdsFromMeshIndices( + const IdArrayType& meshIds, + const vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler* localToGlobalIdRelabeler = + nullptr) const + { // GetGlobalIDsFromMeshIndices() + (void)localToGlobalIdRelabeler; // avoid compiler warning + return vtkm::cont::make_ArrayHandlePermutation(meshIds, this->GlobalMeshIndex); + } // GetGlobalIDsFromMeshIndices() + private: vtkm::cont::Invoker Invoke; @@ -237,10 +276,25 @@ private: }; // ContourTreeMesh +// print content +template +void ContourTreeMesh::PrintContent(std::ostream& outStream /*= std::cout*/) const +{ // PrintContent() + PrintHeader(this->NumVertices, outStream); + //PrintIndices("SortOrder", SortOrder, outStream); + PrintValues("SortedValues", SortedValues, -1, outStream); + PrintIndices("GlobalMeshIndex", GlobalMeshIndex, -1, outStream); + PrintIndices("Neighbours", Neighbours, -1, outStream); + PrintIndices("FirstNeighbour", FirstNeighbour, -1, outStream); + outStream << "MaxNeighbours=" << MaxNeighbours << std::endl; + outStream << "mGetMax=" << mGetMax << std::endl; +} // DebugPrint() // debug routine template -void ContourTreeMesh::DebugPrint(const char* message, const char* fileName, long lineNum) +void ContourTreeMesh::DebugPrint(const char* message, + const char* fileName, + long lineNum) const { // DebugPrint() #ifdef DEBUG_PRINT std::cout << "---------------------------" << std::endl; @@ -251,15 +305,7 @@ void ContourTreeMesh::DebugPrint(const char* message, const char* fil std::cout << "---------------------------" << std::endl; std::cout << std::endl; - PrintHeader(this->NumVertices); - PrintIndices("SortOrder", SortOrder); - PrintValues("SortedValues", SortedValues); - PrintIndices("GlobalMeshIndex", GlobalMeshIndex); - PrintIndices("Neighbours", Neighbours); - PrintIndices("FirstNeighbour", FirstNeighbour); - std::cout << "MaxNeighbours=" << MaxNeighbours << std::endl; - std::cout << "mGetMax=" << mGetMax << std::endl; - + PrintContent(std::cout); #else (void)message; (void)fileName; @@ -267,24 +313,24 @@ void ContourTreeMesh::DebugPrint(const char* message, const char* fil #endif } // DebugPrint() - - - // create the contour tree mesh from contour tree data template ContourTreeMesh::ContourTreeMesh(const IdArrayType& arcs, const IdArrayType& inSortOrder, const vtkm::cont::ArrayHandle& values, const IdArrayType& inGlobalMeshIndex) - : SortOrder(inSortOrder) + : SortOrder() , SortedValues() , GlobalMeshIndex(inGlobalMeshIndex) , Neighbours() , FirstNeighbour() { - this->NumVertices = this->SortOrder.GetNumberOfValues(); + this->NumVertices = inSortOrder.GetNumberOfValues(); + // Initalize the SortedIndices as a smart array handle + this->SortIndices = vtkm::cont::ArrayHandleIndex(this->NumVertices); + this->SortOrder = vtkm::cont::ArrayHandleIndex(this->NumVertices); // values permuted by SortOrder to sort the values - auto permutedValues = vtkm::cont::make_ArrayHandlePermutation(this->SortOrder, values); + auto permutedValues = vtkm::cont::make_ArrayHandlePermutation(inSortOrder, values); // TODO check if we actually need to make this copy here. we could just store the permutedValues array to save memory vtkm::cont::Algorithm::Copy(permutedValues, this->SortedValues); this->InitialiseNeighboursFromArcs(arcs); @@ -311,11 +357,10 @@ ContourTreeMesh::ContourTreeMesh(const IdArrayType& nodes, inSortOrder); auto permutedValues = vtkm::cont::make_ArrayHandlePermutation(permutedSortOrder, values); vtkm::cont::Algorithm::Copy(permutedValues, this->SortedValues); - vtkm::cont::Algorithm::Copy( - permutedSortOrder, - this - ->SortOrder); // TODO Check if the SortOrder needs to be set form the input or the permutted SortOrder + // Initalize the SortedIndices as a smart array handle this->NumVertices = this->SortedValues.GetNumberOfValues(); + this->SortIndices = vtkm::cont::ArrayHandleIndex(this->NumVertices); + this->SortOrder = vtkm::cont::ArrayHandleIndex(this->NumVertices); this->InitialiseNeighboursFromArcs(arcs); #ifdef DEBUG_PRINT // Print the contents fo this for debugging @@ -326,13 +371,15 @@ ContourTreeMesh::ContourTreeMesh(const IdArrayType& nodes, template ContourTreeMesh::ContourTreeMesh(const IdArrayType& arcs, const ContourTreeMesh& mesh) - : SortOrder(mesh.SortOrder) - , SortedValues(mesh.SortedValues) + : SortedValues(mesh.SortedValues) , GlobalMeshIndex(mesh.GlobalMeshIndex) , Neighbours() , FirstNeighbour() { + // Initalize the SortedIndices as a smart array handle this->NumVertices = this->SortedValues.GetNumberOfValues(); + this->SortIndices = vtkm::cont::ArrayHandleIndex(this->NumVertices); + this->SortOrder = vtkm::cont::ArrayHandleIndex(this->NumVertices); this->InitialiseNeighboursFromArcs(arcs); #ifdef DEBUG_PRINT // Print the contents fo this for debugging @@ -345,8 +392,7 @@ template ContourTreeMesh::ContourTreeMesh(const IdArrayType& nodes, const IdArrayType& arcs, const ContourTreeMesh& mesh) - : SortOrder(mesh.SortOrder) - , Neighbours() + : Neighbours() , FirstNeighbour() { // Initatlize the global mesh index with the GlobalMeshIndex permutted by the nodes @@ -358,6 +404,8 @@ ContourTreeMesh::ContourTreeMesh(const IdArrayType& nodes, vtkm::cont::Algorithm::Copy(permutedSortedValues, this->SortedValues); // Initialize the neighbours from the arcs this->NumVertices = this->SortedValues.GetNumberOfValues(); + this->SortIndices = vtkm::cont::ArrayHandleIndex(this->NumVertices); + this->SortOrder = vtkm::cont::ArrayHandleIndex(this->NumVertices); this->InitialiseNeighboursFromArcs(arcs); #ifdef DEBUG_PRINT // Print the contents fo this for debugging @@ -479,7 +527,7 @@ struct NotNoSuchElement template template void ContourTreeMesh::MergeWith(ContourTreeMesh& other) -{ +{ // Merge With #ifdef DEBUG_PRINT this->DebugPrint("THIS ContourTreeMesh", __FILE__, __LINE__); other.DebugPrint("OTHER ContourTreeMesh", __FILE__, __LINE__); @@ -495,8 +543,8 @@ void ContourTreeMesh::MergeWith(ContourTreeMesh& other) //auto allGlobalIndices = CombinedVectorthisGlobalMeshIndex, other.GlobalMeshIndex); // Create combined sort order - IdArrayType - overallSortOrder; // TODO This vector could potentially be implemented purely as a smart array handle to reduce memory usage + // TODO This vector could potentially be implemented purely as a smart array handle to reduce memory usage + IdArrayType overallSortOrder; overallSortOrder.Allocate(this->NumVertices + other.NumVertices); { // Create a new scope so that the following two vectors get deleted when leaving the scope @@ -725,7 +773,8 @@ void ContourTreeMesh::MergeWith(ContourTreeMesh& other) this->Neighbours = combinedNeighbours; this->FirstNeighbour = combinedFirstNeighbour; this->NumVertices = SortedValues.GetNumberOfValues(); - // TODO Do we need to set the sort order as well? + this->SortIndices = vtkm::cont::ArrayHandleIndex(this->NumVertices); + this->SortOrder = vtkm::cont::ArrayHandleIndex(this->NumVertices); // Re-compute maximum number of neigbours ComputeMaxNeighbours(); @@ -734,14 +783,13 @@ void ContourTreeMesh::MergeWith(ContourTreeMesh& other) // Print the contents fo this for debugging DebugPrint("ContourTreeMeshes merged", __FILE__, __LINE__); #endif -} +} // Merge With template void ContourTreeMesh::Save(const char* filename) const { std::ofstream os(filename); - SaveVector(os, this->SortOrder); SaveVector(os, this->SortedValues); SaveVector(os, this->GlobalMeshIndex); SaveVector(os, this->Neighbours); @@ -752,12 +800,14 @@ template void ContourTreeMesh::Load(const char* filename) { std::ifstream is(filename); - LoadVector(is, this->SortOrder); LoadVector(is, this->SortedValues); LoadVector(is, this->GlobalMeshIndex); LoadVector(is, this->Neighbours); LoadVector(is, this->FirstNeighbour); this->ComputeMaxNeighbours(); + this->NumVertices = this->SortedValues.GetNumberOfValues(); + this->SortOrder = vtkm::cont::ArrayHandleIndex(this->NumVertices); + this->SortIndices = vtkm::cont::ArrayHandleIndex(this->NumVertices); } template @@ -766,10 +816,13 @@ void ContourTreeMesh::SaveVector(std::ostream& os, const vtkm::cont::ArrayHandle& vec) const { vtkm::Id numVals = vec.GetNumberOfValues(); - os.write(reinterpret_cast(&numVals), sizeof(ValueType)); + //os.write(reinterpret_cast(&numVals), sizeof(ValueType)); + os << numVals << ": "; auto vecPortal = vec.ReadPortal(); for (vtkm::Id i = 0; i < numVals; ++i) - os.write(reinterpret_cast(vecPortal.Get(i)), sizeof(ValueType)); + os << vecPortal.Get(i) << " "; + //os.write(reinterpret_cast(vecPortal.Get(i)), sizeof(ValueType)); + os << std::endl; } template @@ -791,13 +844,11 @@ void ContourTreeMesh::LoadVector(std::istream& is, template MeshBoundaryContourTreeMeshExec ContourTreeMesh::GetMeshBoundaryExecutionObject( - vtkm::Id totalNRows, - vtkm::Id totalNCols, + vtkm::Id3 globalSize, vtkm::Id3 minIdx, vtkm::Id3 maxIdx) const { - return MeshBoundaryContourTreeMeshExec( - this->GlobalMeshIndex, totalNRows, totalNCols, minIdx, maxIdx); + return MeshBoundaryContourTreeMeshExec(this->GlobalMeshIndex, globalSize, minIdx, maxIdx); } template @@ -824,7 +875,6 @@ void ContourTreeMesh::GetBoundaryVertices( vtkm::cont::Algorithm::Copy(boundaryVertexArray, boundarySortIndexArray); } - } // namespace contourtree_augmented } // worklet } // vtkm diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/Freudenthal_2D_Triangulation.h b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation2DFreudenthal.h similarity index 71% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/Freudenthal_2D_Triangulation.h rename to vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation2DFreudenthal.h index ac7632c1b..50d4fc365 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/Freudenthal_2D_Triangulation.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation2DFreudenthal.h @@ -50,16 +50,16 @@ // Oliver Ruebel (LBNL) //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_2d_freudenthal_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_2d_freudenthal_h +#ifndef vtk_m_worklet_contourtree_augmented_data_set_mesh_triangulation_2d_freudenthal_h +#define vtk_m_worklet_contourtree_augmented_data_set_mesh_triangulation_2d_freudenthal_h #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include @@ -70,14 +70,14 @@ namespace worklet namespace contourtree_augmented { -template -class Mesh_DEM_Triangulation_2D_Freudenthal - : public Mesh_DEM_Triangulation_2D +class DataSetMeshTriangulation2DFreudenthal + : public DataSetMesh , public vtkm::cont::ExecutionObjectBase -{ // class Mesh_DEM_Triangulation +{ // class DataSetMeshTriangulation public: // Constants and case tables m2d_freudenthal::EdgeBoundaryDetectionMasksType EdgeBoundaryDetectionMasks; + static constexpr int MAX_OUTDEGREE = 3; //Mesh dependent helper functions void SetPrepareForExecutionBehavior(bool getMax); @@ -86,7 +86,7 @@ public: MeshStructureFreudenthal2D PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const; - Mesh_DEM_Triangulation_2D_Freudenthal(vtkm::Id ncols, vtkm::Id nrows); + DataSetMeshTriangulation2DFreudenthal(vtkm::Id2 meshSize); MeshBoundary2DExec GetMeshBoundaryExecutionObject() const; @@ -98,39 +98,30 @@ public: private: bool UseGetMax; // Define the behavior ofr the PrepareForExecution function -}; // class Mesh_DEM_Triangulation +}; // class DataSetMeshTriangulation // creates input mesh -template -Mesh_DEM_Triangulation_2D_Freudenthal::Mesh_DEM_Triangulation_2D_Freudenthal( - vtkm::Id ncols, - vtkm::Id nrows) - : Mesh_DEM_Triangulation_2D(ncols, nrows) - +DataSetMeshTriangulation2DFreudenthal::DataSetMeshTriangulation2DFreudenthal(vtkm::Id2 meshSize) + : DataSetMesh(vtkm::Id3{ meshSize[0], meshSize[1], 1 }) + , EdgeBoundaryDetectionMasks{ vtkm::cont::make_ArrayHandle( + m2d_freudenthal::EdgeBoundaryDetectionMasks, + m2d_freudenthal::N_INCIDENT_EDGES, + vtkm::CopyFlag::Off) } { - this->EdgeBoundaryDetectionMasks = - vtkm::cont::make_ArrayHandle(m2d_freudenthal::EdgeBoundaryDetectionMasks, - m2d_freudenthal::N_INCIDENT_EDGES, - vtkm::CopyFlag::Off); } -template -void Mesh_DEM_Triangulation_2D_Freudenthal::SetPrepareForExecutionBehavior( - bool getMax) +void DataSetMeshTriangulation2DFreudenthal::SetPrepareForExecutionBehavior(bool getMax) { this->UseGetMax = getMax; } // Get VTKM execution object that represents the structure of the mesh and provides the mesh helper functions on the device -template template -MeshStructureFreudenthal2D -Mesh_DEM_Triangulation_2D_Freudenthal::PrepareForExecution( +MeshStructureFreudenthal2D DataSetMeshTriangulation2DFreudenthal::PrepareForExecution( DeviceTag, vtkm::cont::Token& token) const { - return MeshStructureFreudenthal2D(this->NumColumns, - this->NumRows, + return MeshStructureFreudenthal2D(vtkm::Id2{ this->MeshSize[0], this->MeshSize[1] }, m2d_freudenthal::N_INCIDENT_EDGES, this->UseGetMax, this->SortIndices, @@ -139,23 +130,19 @@ Mesh_DEM_Triangulation_2D_Freudenthal::PrepareForExecution( token); } -template -MeshBoundary2DExec -Mesh_DEM_Triangulation_2D_Freudenthal::GetMeshBoundaryExecutionObject() const +MeshBoundary2DExec DataSetMeshTriangulation2DFreudenthal::GetMeshBoundaryExecutionObject() const { - return MeshBoundary2DExec(this->NumColumns, this->NumRows, this->SortOrder); + return MeshBoundary2DExec(vtkm::Id2{ this->MeshSize[0], this->MeshSize[1] }, this->SortIndices); } - -template -void Mesh_DEM_Triangulation_2D_Freudenthal::GetBoundaryVertices( +void DataSetMeshTriangulation2DFreudenthal::GetBoundaryVertices( IdArrayType& boundaryVertexArray, // output IdArrayType& boundarySortIndexArray, // output MeshBoundary2DExec* meshBoundaryExecObj // optional input, included for consistency with ContourTreeMesh ) const { - vtkm::Id numBoundary = 2 * this->NumRows + 2 * this->NumColumns - 4; + vtkm::Id numBoundary = 2 * this->MeshSize[1] + 2 * this->MeshSize[0] - 4; auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary); ComputeMeshBoundary2D computeMeshBoundary2dWorklet; this->Invoke(computeMeshBoundary2dWorklet, @@ -168,7 +155,6 @@ void Mesh_DEM_Triangulation_2D_Freudenthal::GetBoundaryVertices( ); } - } // namespace contourtree_augmented } // worklet } // vtkm diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/Freudenthal_3D_Triangulation.h b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DFreudenthal.h similarity index 73% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/Freudenthal_3D_Triangulation.h rename to vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DFreudenthal.h index 7a3b8a1ea..bdb2d6032 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/Freudenthal_3D_Triangulation.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DFreudenthal.h @@ -51,8 +51,8 @@ //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_3d_freudenthal_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_3d_freudenthal_h +#ifndef vtk_m_worklet_contourtree_augmented_data_set_mesh_triangulation_3d_freudenthal_h +#define vtk_m_worklet_contourtree_augmented_data_set_mesh_triangulation_3d_freudenthal_h #include #include @@ -60,11 +60,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace vtkm { @@ -73,16 +73,16 @@ namespace worklet namespace contourtree_augmented { -template -class Mesh_DEM_Triangulation_3D_Freudenthal - : public Mesh_DEM_Triangulation_3D +class DataSetMeshTriangulation3DFreudenthal + : public DataSetMesh , public vtkm::cont::ExecutionObjectBase -{ // class Mesh_DEM_Triangulation +{ // class DataSetMeshTriangulation3DFreudenthal public: // Constants and case tables m3d_freudenthal::EdgeBoundaryDetectionMasksType EdgeBoundaryDetectionMasks; m3d_freudenthal::NeighbourOffsetsType NeighbourOffsets; m3d_freudenthal::LinkComponentCaseTableType LinkComponentCaseTable; + static constexpr int MAX_OUTDEGREE = 6; // True for Freudenthal and Marching Cubes // Mesh helper functions void SetPrepareForExecutionBehavior(bool getMax); @@ -91,7 +91,7 @@ public: MeshStructureFreudenthal3D PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const; - Mesh_DEM_Triangulation_3D_Freudenthal(vtkm::Id ncols, vtkm::Id nrows, vtkm::Id nslices); + DataSetMeshTriangulation3DFreudenthal(vtkm::Id3 meshSize); MeshBoundary3DExec GetMeshBoundaryExecutionObject() const; @@ -103,15 +103,11 @@ public: private: bool UseGetMax; // Define the behavior ofr the PrepareForExecution function -}; // class Mesh_DEM_Triangulation +}; // class DataSetMeshTriangulation // creates input mesh -template -Mesh_DEM_Triangulation_3D_Freudenthal::Mesh_DEM_Triangulation_3D_Freudenthal( - vtkm::Id ncols, - vtkm::Id nrows, - vtkm::Id nslices) - : Mesh_DEM_Triangulation_3D(ncols, nrows, nslices) +DataSetMeshTriangulation3DFreudenthal::DataSetMeshTriangulation3DFreudenthal(vtkm::Id3 meshSize) + : DataSetMesh(meshSize) { // Initialize the case tables in vtkm @@ -127,25 +123,18 @@ Mesh_DEM_Triangulation_3D_Freudenthal::Mesh_DEM_Triangulation_3D vtkm::CopyFlag::Off); } - -template -void Mesh_DEM_Triangulation_3D_Freudenthal::SetPrepareForExecutionBehavior( - bool getMax) +void DataSetMeshTriangulation3DFreudenthal::SetPrepareForExecutionBehavior(bool getMax) { this->UseGetMax = getMax; } // Get VTKM execution object that represents the structure of the mesh and provides the mesh helper functions on the device -template template -MeshStructureFreudenthal3D -Mesh_DEM_Triangulation_3D_Freudenthal::PrepareForExecution( +MeshStructureFreudenthal3D DataSetMeshTriangulation3DFreudenthal::PrepareForExecution( DeviceTag, vtkm::cont::Token& token) const { - return MeshStructureFreudenthal3D(this->NumColumns, - this->NumRows, - this->NumSlices, + return MeshStructureFreudenthal3D(this->MeshSize, m3d_freudenthal::N_INCIDENT_EDGES, this->UseGetMax, this->SortIndices, @@ -156,24 +145,20 @@ Mesh_DEM_Triangulation_3D_Freudenthal::PrepareForExecution( token); } - -template -MeshBoundary3DExec -Mesh_DEM_Triangulation_3D_Freudenthal::GetMeshBoundaryExecutionObject() const +MeshBoundary3DExec DataSetMeshTriangulation3DFreudenthal::GetMeshBoundaryExecutionObject() const { - return MeshBoundary3DExec(this->NumColumns, this->NumRows, this->NumSlices, this->SortOrder); + return MeshBoundary3DExec(this->MeshSize, this->SortIndices); } -template -void Mesh_DEM_Triangulation_3D_Freudenthal::GetBoundaryVertices( +void DataSetMeshTriangulation3DFreudenthal::GetBoundaryVertices( IdArrayType& boundaryVertexArray, // output IdArrayType& boundarySortIndexArray, // output MeshBoundary3DExec* meshBoundaryExecObj // input ) const { - vtkm::Id numBoundary = 2 * this->NumRows * this->NumColumns // xy faces - + 2 * this->NumRows * (this->NumSlices - 2) // yz faces - excluding vertices on xy - + 2 * (this->NumColumns - 2) * (this->NumSlices - 2); // xz face interiors + vtkm::Id numBoundary = 2 * this->MeshSize[1] * this->MeshSize[0] // xy faces + + 2 * this->MeshSize[1] * (this->MeshSize[2] - 2) // yz faces - excluding vertices on xy + + 2 * (this->MeshSize[0] - 2) * (this->MeshSize[2] - 2); // xz face interiors auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary); ComputeMeshBoundary3D computeMeshBoundary3dWorklet; this->Invoke(computeMeshBoundary3dWorklet, diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MarchingCubes_3D_Triangulation.h b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DMarchingCubes.h similarity index 75% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MarchingCubes_3D_Triangulation.h rename to vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DMarchingCubes.h index d0a76c47f..7dec2fd73 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MarchingCubes_3D_Triangulation.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DMarchingCubes.h @@ -51,8 +51,8 @@ //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_3d_marchingcubes_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_triangulation_3d_marchingcubes_h +#ifndef vtk_m_worklet_contourtree_augmented_data_set_mesh_triangulation_3d_marchingcubes_h +#define vtk_m_worklet_contourtree_augmented_data_set_mesh_triangulation_3d_marchingcubes_h #include #include @@ -60,11 +60,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace vtkm { @@ -73,11 +73,10 @@ namespace worklet namespace contourtree_augmented { -template -class Mesh_DEM_Triangulation_3D_MarchingCubes - : public Mesh_DEM_Triangulation_3D +class DataSetMeshTriangulation3DMarchingCubes + : public DataSetMesh , public vtkm::cont::ExecutionObjectBase -{ // class Mesh_DEM_Triangulation +{ // class DataSetMeshTriangulation3DMarchingCubes public: //Constants and case tables @@ -87,6 +86,7 @@ public: m3d_marchingcubes::LinkVertexConnectionsType LinkVertexConnectionsEighteen; m3d_marchingcubes::InCubeConnectionsType InCubeConnectionsSix; m3d_marchingcubes::InCubeConnectionsType InCubeConnectionsEighteen; + static constexpr int MAX_OUTDEGREE = 6; // True for Freudenthal and Marching Cubes // mesh depended helper functions void SetPrepareForExecutionBehavior(bool getMax); @@ -95,27 +95,24 @@ public: MeshStructureMarchingCubes PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const; - Mesh_DEM_Triangulation_3D_MarchingCubes(vtkm::Id ncols, vtkm::Id nrows, vtkm::Id nslices); + DataSetMeshTriangulation3DMarchingCubes(vtkm::Id3 meshSize); MeshBoundary3DExec GetMeshBoundaryExecutionObject() const; - void GetBoundaryVertices(IdArrayType& boundaryVertexArray, // output - IdArrayType& boundarySortIndexArray, // output - MeshBoundary3DExec* meshBoundaryExecObj = - NULL // optional input, included for consistency with ContourTreeMesh + void GetBoundaryVertices( + IdArrayType& boundaryVertexArray, // output + IdArrayType& boundarySortIndexArray, // output + MeshBoundary3DExec* meshBoundaryExecObj = + nullptr // optional input, included for consistency with ContourTreeMesh ) const; private: bool UseGetMax; // Define the behavior ofr the PrepareForExecution function -}; // class Mesh_DEM_Triangulation +}; // class DataSetMesh_Triangulation // creates input mesh -template -Mesh_DEM_Triangulation_3D_MarchingCubes::Mesh_DEM_Triangulation_3D_MarchingCubes( - vtkm::Id ncols, - vtkm::Id nrows, - vtkm::Id nslices) - : Mesh_DEM_Triangulation_3D(ncols, nrows, nslices) +DataSetMeshTriangulation3DMarchingCubes::DataSetMeshTriangulation3DMarchingCubes(vtkm::Id3 meshSize) + : DataSetMesh(meshSize) { // Initialize the case tables in vtkm @@ -157,24 +154,18 @@ Mesh_DEM_Triangulation_3D_MarchingCubes::Mesh_DEM_Triangulation_ vtkm::CopyFlag::Off); } -template -void Mesh_DEM_Triangulation_3D_MarchingCubes::SetPrepareForExecutionBehavior( - bool getMax) +void DataSetMeshTriangulation3DMarchingCubes::SetPrepareForExecutionBehavior(bool getMax) { this->UseGetMax = getMax; } // Get VTKM execution object that represents the structure of the mesh and provides the mesh helper functions on the device -template template -MeshStructureMarchingCubes -Mesh_DEM_Triangulation_3D_MarchingCubes::PrepareForExecution( +MeshStructureMarchingCubes DataSetMeshTriangulation3DMarchingCubes::PrepareForExecution( DeviceTag, vtkm::cont::Token& token) const { - return MeshStructureMarchingCubes(this->NumColumns, - this->NumRows, - this->NumSlices, + return MeshStructureMarchingCubes(this->MeshSize, this->UseGetMax, this->SortIndices, this->SortOrder, @@ -187,23 +178,20 @@ Mesh_DEM_Triangulation_3D_MarchingCubes::PrepareForExecution( token); } -template -MeshBoundary3DExec -Mesh_DEM_Triangulation_3D_MarchingCubes::GetMeshBoundaryExecutionObject() const +MeshBoundary3DExec DataSetMeshTriangulation3DMarchingCubes::GetMeshBoundaryExecutionObject() const { - return MeshBoundary3DExec(this->NumColumns, this->NumRows, this->NumSlices, this->SortOrder); + return MeshBoundary3DExec(this->MeshSize, this->SortOrder); } -template -void Mesh_DEM_Triangulation_3D_MarchingCubes::GetBoundaryVertices( +void DataSetMeshTriangulation3DMarchingCubes::GetBoundaryVertices( IdArrayType& boundaryVertexArray, // output IdArrayType& boundarySortIndexArray, // output MeshBoundary3DExec* meshBoundaryExecObj // input ) const { - vtkm::Id numBoundary = 2 * this->NumRows * this->NumColumns // xy faces - + 2 * this->NumRows * (this->NumSlices - 2) // yz faces - excluding vertices on xy - + 2 * (this->NumColumns - 2) * (this->NumSlices - 2); // xz face interiors + vtkm::Id numBoundary = 2 * this->MeshSize[1] * this->MeshSize[0] // xy faces + + 2 * this->MeshSize[1] * (this->MeshSize[2] - 2) // yz faces - excluding vertices on xy + + 2 * (this->MeshSize[0] - 2) * (this->MeshSize[2] - 2); // xz face interiors auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary); ComputeMeshBoundary3D computeMeshBoundary3dWorklet; this->Invoke(computeMeshBoundary3dWorklet, diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureContourTreeMesh.h b/vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureContourTreeMesh.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureContourTreeMesh.h rename to vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureContourTreeMesh.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal2D.h b/vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureFreudenthal2D.h similarity index 85% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal2D.h rename to vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureFreudenthal2D.h index 786799056..1d5e875b6 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal2D.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureFreudenthal2D.h @@ -50,15 +50,15 @@ // Oliver Ruebel (LBNL) //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_MeshStructureFreudenthal2D_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_MeshStructureFreudenthal2D_h +#ifndef vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureFreudenthal2D_h +#define vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureFreudenthal2D_h #include #include #include #include -#include -#include +#include +#include namespace vtkm @@ -70,7 +70,7 @@ namespace contourtree_augmented // Worklet for computing the sort indices from the sort order template -class MeshStructureFreudenthal2D : public mesh_dem::MeshStructure2D +class MeshStructureFreudenthal2D : public data_set_mesh::MeshStructure2D { public: using SortIndicesPortalType = @@ -82,7 +82,7 @@ public: // Default constucture. Needed for the CUDA built to work VTKM_EXEC_CONT MeshStructureFreudenthal2D() - : mesh_dem::MeshStructure2D() + : data_set_mesh::MeshStructure2D() , GetMax(false) , NumIncidentEdges(m2d_freudenthal::N_INCIDENT_EDGES) { @@ -90,15 +90,14 @@ public: // Main constructor used in the code MeshStructureFreudenthal2D( - vtkm::Id ncols, - vtkm::Id nrows, + vtkm::Id2 meshSize, vtkm::Int32 nincident_edges, bool getmax, const IdArrayType& sortIndices, const IdArrayType& SortOrder, const m2d_freudenthal::EdgeBoundaryDetectionMasksType& EdgeBoundaryDetectionMasksIn, vtkm::cont::Token& token) - : mesh_dem::MeshStructure2D(ncols, nrows) + : data_set_mesh::MeshStructure2D(meshSize) , GetMax(getmax) , NumIncidentEdges(nincident_edges) { @@ -118,17 +117,17 @@ public: switch (edgeNo) { case 0: - return this->SortIndicesPortal.Get(meshIndex + 1); // row , col + 1 + return this->SortIndicesPortal.Get(meshIndex + 1); // [1] , [0] + 1 case 1: - return this->SortIndicesPortal.Get(meshIndex + this->NumColumns + 1); // row + 1, col + 1 + return this->SortIndicesPortal.Get(meshIndex + this->MeshSize[0] + 1); // [1] + 1, [0] + 1 case 2: - return this->SortIndicesPortal.Get(meshIndex + this->NumColumns); // row + 1, col + return this->SortIndicesPortal.Get(meshIndex + this->MeshSize[0]); // [1] + 1, [0] case 3: - return this->SortIndicesPortal.Get(meshIndex - 1); // row , col - 1 + return this->SortIndicesPortal.Get(meshIndex - 1); // [1] , [0] - 1 case 4: - return this->SortIndicesPortal.Get(meshIndex - this->NumColumns - 1); // row - 1, col - 1 + return this->SortIndicesPortal.Get(meshIndex - this->MeshSize[0] - 1); // [1] - 1, [0] - 1 case 5: - return this->SortIndicesPortal.Get(meshIndex - this->NumColumns); // row - 1, col + return this->SortIndicesPortal.Get(meshIndex - this->MeshSize[0]); // [1] - 1, [0] default: return -1; // TODO How to generate a meaningful error message from a device (in particular when using CUDA?) } @@ -154,11 +153,10 @@ public: vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex); // get the row and column - vtkm::Id row = this->VertexRow(meshIndex); - vtkm::Id col = this->VertexColumn(meshIndex); - vtkm::Int8 boundaryConfig = ((col == 0) ? LeftBit : 0) | - ((col == this->NumColumns - 1) ? RightBit : 0) | ((row == 0) ? TopBit : 0) | - ((row == this->NumRows - 1) ? BottomBit : 0); + vtkm::Id2 pos = this->VertexPos(meshIndex); + vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) | + ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) | + ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0); // in what follows, the boundary conditions always reset wasAscent for (vtkm::Id edgeNo = 0; edgeNo < this->NumIncidentEdges; edgeNo++) @@ -194,11 +192,10 @@ public: vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex); // get the row and column - vtkm::Id row = this->VertexRow(meshIndex); - vtkm::Id col = this->VertexColumn(meshIndex); - vtkm::Int8 boundaryConfig = ((col == 0) ? LeftBit : 0) | - ((col == this->NumColumns - 1) ? RightBit : 0) | ((row == 0) ? TopBit : 0) | - ((row == this->NumRows - 1) ? BottomBit : 0); + vtkm::Id2 pos = this->VertexPos(meshIndex); + vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) | + ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) | + ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0); // and initialise the mask vtkm::Id neighbourhoodMask = 0; diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal3D.h b/vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureFreudenthal3D.h similarity index 85% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal3D.h rename to vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureFreudenthal3D.h index e95579f87..6cc8111b9 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal3D.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureFreudenthal3D.h @@ -50,16 +50,16 @@ // Oliver Ruebel (LBNL) //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_MeshStructureFreudenthal3D_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_MeshStructureFreudenthal3D_h +#ifndef vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureFreudenthal3D_h +#define vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureFreudenthal3D_h #include #include #include #include #include -#include -#include +#include +#include namespace vtkm @@ -71,7 +71,7 @@ namespace contourtree_augmented // Worklet for computing the sort indices from the sort order template -class MeshStructureFreudenthal3D : public mesh_dem::MeshStructure3D +class MeshStructureFreudenthal3D : public data_set_mesh::MeshStructure3D { public: using SortIndicesPortalType = @@ -92,7 +92,7 @@ public: // Default constructor needed to make the CUDA build work VTKM_EXEC_CONT MeshStructureFreudenthal3D() - : mesh_dem::MeshStructure3D() + : data_set_mesh::MeshStructure3D() , GetMax(false) , NumIncidentEdge(m3d_freudenthal::N_INCIDENT_EDGES) { @@ -100,9 +100,7 @@ public: // Main constructore used in the code MeshStructureFreudenthal3D( - vtkm::Id ncols, - vtkm::Id nrows, - vtkm::Id nslices, + vtkm::Id3 meshSize, vtkm::Id nincident_edges, bool getmax, const IdArrayType& sortIndices, @@ -111,7 +109,7 @@ public: const m3d_freudenthal::NeighbourOffsetsType& neighbourOffsetsIn, const m3d_freudenthal::LinkComponentCaseTableType& linkComponentCaseTableIn, vtkm::cont::Token& token) - : mesh_dem::MeshStructure3D(ncols, nrows, nslices) + : data_set_mesh::MeshStructure3D(meshSize) , GetMax(getmax) , NumIncidentEdge(nincident_edges) { @@ -132,10 +130,12 @@ public: inline vtkm::Id GetNeighbourIndex(vtkm::Id sortIndex, vtkm::Id edgeNo) const { // GetNeighbourIndex vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex); + // NOTE: Offsets are stored in "reversed" zyx [2][1][0] order (remaining artifact from + // using slices, rows, columns instead of xyz/[0][1][2]) return SortIndicesPortal.Get(meshIndex + - (NeighbourOffsetsPortal.Get(edgeNo)[0] * this->NumRows + + (NeighbourOffsetsPortal.Get(edgeNo)[0] * this->MeshSize[1] + NeighbourOffsetsPortal.Get(edgeNo)[1]) * - this->NumColumns + + this->MeshSize[0] + NeighbourOffsetsPortal.Get(edgeNo)[2]); } // GetNeighbourIndex @@ -159,14 +159,11 @@ public: using namespace m3d_freudenthal; vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex); - vtkm::Id slice = this->VertexSlice(meshIndex); - vtkm::Id row = this->VertexRow(meshIndex); - vtkm::Id col = this->VertexColumn(meshIndex); - - vtkm::Int8 boundaryConfig = ((slice == 0) ? FrontBit : 0) | - ((slice == this->NumSlices - 1) ? BackBit : 0) | ((col == 0) ? LeftBit : 0) | - ((col == this->NumColumns - 1) ? RightBit : 0) | ((row == 0) ? TopBit : 0) | - ((row == this->NumRows - 1) ? BottomBit : 0); + vtkm::Id3 pos = this->VertexPos(meshIndex); + vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) | + ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) | + ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0) | ((pos[2] == 0) ? FrontBit : 0) | + ((pos[2] == this->MeshSize[2] - 1) ? BackBit : 0); // in what follows, the boundary conditions always reset wasAscent // loop downwards so that we pick the same edges as previous versions @@ -199,13 +196,11 @@ public: vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex); // get the row and column - vtkm::Id slice = this->VertexSlice(meshIndex); - vtkm::Id row = this->VertexRow(meshIndex); - vtkm::Id col = this->VertexColumn(meshIndex); - vtkm::Int8 boundaryConfig = ((slice == 0) ? FrontBit : 0) | - ((slice == this->NumSlices - 1) ? BackBit : 0) | ((col == 0) ? LeftBit : 0) | - ((col == this->NumColumns - 1) ? RightBit : 0) | ((row == 0) ? TopBit : 0) | - ((row == this->NumRows - 1) ? BottomBit : 0); + vtkm::Id3 pos = this->VertexPos(meshIndex); + vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) | + ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) | + ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0) | ((pos[2] == 0) ? FrontBit : 0) | + ((pos[2] == this->MeshSize[2] - 1) ? BackBit : 0); // Initialize "union find" vtkm::Id caseNo = 0; diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureMarchingCubes.h b/vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureMarchingCubes.h similarity index 69% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureMarchingCubes.h rename to vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureMarchingCubes.h index 5e0ded8d5..097b0c5ad 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureMarchingCubes.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureMarchingCubes.h @@ -50,16 +50,16 @@ // Oliver Ruebel (LBNL) //============================================================================== -#ifndef vtk_m_worklet_contourtree_augmented_mesh_dem_MeshStructureMarchingCubes_h -#define vtk_m_worklet_contourtree_augmented_mesh_dem_MeshStructureMarchingCubes_h +#ifndef vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureMarchingCubes_h +#define vtk_m_worklet_contourtree_augmented_meshtypes_MeshStructureMarchingCubes_h #include #include #include #include #include -#include -#include +#include +#include namespace vtkm { @@ -70,7 +70,7 @@ namespace contourtree_augmented // Worklet for computing the sort indices from the sort order template -class MeshStructureMarchingCubes : public mesh_dem::MeshStructure3D +class MeshStructureMarchingCubes : public data_set_mesh::MeshStructure3D { public: // EdgeBoundaryDetectionMasks types @@ -100,16 +100,14 @@ public: // Default constructor needed to make the CUDA build work VTKM_EXEC_CONT MeshStructureMarchingCubes() - : mesh_dem::MeshStructure3D() + : data_set_mesh::MeshStructure3D() , GetMax(false) { } // Main constructore used in the code MeshStructureMarchingCubes( - vtkm::Id ncols, - vtkm::Id nrows, - vtkm::Id nslices, + vtkm::Id3 meshSize, bool getmax, const IdArrayType& sortIndices, const IdArrayType& sortOrder, @@ -120,7 +118,7 @@ public: const m3d_marchingcubes::InCubeConnectionsType& InCubeConnectionsSixIn, const m3d_marchingcubes::InCubeConnectionsType& InCubeConnectionsEighteenIn, vtkm::cont::Token& token) - : mesh_dem::MeshStructure3D(ncols, nrows, nslices) + : data_set_mesh::MeshStructure3D(meshSize) , GetMax(getmax) { this->SortIndicesPortal = sortIndices.PrepareForInput(DeviceAdapter(), token); @@ -150,84 +148,69 @@ public: { using namespace m3d_marchingcubes; vtkm::Id meshIndex = this->SortOrderPortal.Get(sortIndex); + const vtkm::Id3 strides{ 1, this->MeshSize[0], this->MeshSize[0] * this->MeshSize[1] }; + // GetNeighbourIndex switch (nbrNo) { // Edge connected neighbours - case 0: - return SortIndicesPortal.Get(meshIndex - - (this->NumRows * this->NumColumns)); // { -1, 0, 0 } - case 1: - return SortIndicesPortal.Get(meshIndex - this->NumColumns); // { 0, -1, 0 } - case 2: - return SortIndicesPortal.Get(meshIndex - 1); // { 0, 0, -1 } - case 3: - return SortIndicesPortal.Get(meshIndex + 1); // { 0, 0, 1 } - case 4: - return SortIndicesPortal.Get(meshIndex + this->NumColumns); // { 0, 1, 0 } + case 0: // { 0, 0, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2]); + case 1: // { 0, -1, 0 } + return SortIndicesPortal.Get(meshIndex - strides[1]); + case 2: // { -1, 0, 0 } + return SortIndicesPortal.Get(meshIndex - strides[0]); + case 3: // { 1, 0, 0 } + return SortIndicesPortal.Get(meshIndex + strides[0]); + case 4: // { 0, 1, 0 } + return SortIndicesPortal.Get(meshIndex + strides[1]); + case 5: // { 0, 0, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2]); // Face connected neighbours - case 5: - return SortIndicesPortal.Get(meshIndex + - (this->NumRows * this->NumColumns)); // { 1, 0, 0 } - case 6: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) - - this->NumColumns); // { -1, -1, 0 } - case 7: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) - - 1); // { -1, 0, -1 } - case 8: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) + - 1); // { -1, 0, 1 } - case 9: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) + - this->NumColumns); // { -1, 1, 0 } - case 10: - return SortIndicesPortal.Get(meshIndex - this->NumColumns - 1); // { 0, -1, -1 } - case 11: - return SortIndicesPortal.Get(meshIndex - this->NumColumns + 1); // { 0, -1, 1 } - case 12: - return SortIndicesPortal.Get(meshIndex + this->NumColumns - 1); // { 0, 1, -1 } - case 13: - return SortIndicesPortal.Get(meshIndex + this->NumColumns + 1); // { 0, 1, 1 } - case 14: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) - - this->NumColumns); // { 1, -1, 0 } - case 15: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) - - 1); // { 1, 0, -1 } - case 16: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) + - 1); // { 1, 0, 1 } - case 17: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) + - this->NumColumns); // { 1, 1, 0 } + case 6: // { 0, -1, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] - strides[1]); + case 7: // { -1, 0, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] - strides[0]); + case 8: // { 1, 0, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] + strides[0]); + case 9: // { 0, 1, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] + strides[1]); + case 10: // { -1, -1, 0 } + return SortIndicesPortal.Get(meshIndex - strides[1] - strides[0]); + case 11: // { 1, -1, 0 } + return SortIndicesPortal.Get(meshIndex - strides[1] + strides[0]); + case 12: // { -1, 1, 0 } + return SortIndicesPortal.Get(meshIndex + strides[1] - strides[0]); + case 13: // { 1, 1, 0 } + return SortIndicesPortal.Get(meshIndex + strides[1] + strides[0]); + case 14: // { 0, -1, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] - strides[1]); + case 15: // { -1, 0, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] - 1); + case 16: // { 1, 0, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] + 1); + case 17: // { 0, 1, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] + strides[1]); // Diagonal connected neighbours - case 18: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) - - this->NumColumns - 1); // { -1, -1, -1 } - case 19: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) - - this->NumColumns + 1); // { -1, -1, 1 } - case 20: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) + - this->NumColumns - 1); // { -1, 1, -1 } - case 21: - return SortIndicesPortal.Get(meshIndex - (this->NumRows * this->NumColumns) + - this->NumColumns + 1); // { -1, 1, 1 } - case 22: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) - - this->NumColumns - 1); // { 1, -1, -1 } - case 23: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) - - this->NumColumns + 1); // { 1, -1, 1 } - case 24: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) + - this->NumColumns - 1); // { 1, 1, -1 } - case 25: - return SortIndicesPortal.Get(meshIndex + (this->NumRows * this->NumColumns) + - this->NumColumns + 1); // { 1, 1, 1 } + case 18: // { -1, -1, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] - strides[1] - strides[0]); + case 19: // { 1, -1, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] - strides[1] + strides[0]); + case 20: // { -1, 1, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] + strides[1] - strides[0]); + case 21: // { 1, 1, -1 } + return SortIndicesPortal.Get(meshIndex - strides[2] + strides[1] + strides[0]); + case 22: // { -1, -1, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] - strides[1] - strides[0]); + case 23: // { 1, -1, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] - strides[1] + strides[0]); + case 24: // { -1, 1, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] + strides[1] - strides[0]); + case 25: // { 1, 1, 1 } + return SortIndicesPortal.Get(meshIndex + strides[2] + strides[1] + strides[0]); default: - assert(false); + VTKM_ASSERT(false); + // TODO/FIXME: Should probaly return an invalid value or throw an exception instead return meshIndex; // Need to error out here } } // GetNeighbourIndex @@ -251,13 +234,11 @@ public: // convert to a sort index vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex); - vtkm::Id slice = this->VertexSlice(meshIndex); - vtkm::Id row = this->VertexRow(meshIndex); - vtkm::Id col = this->VertexColumn(meshIndex); - vtkm::Int8 boundaryConfig = ((slice == 0) ? FrontBit : 0) | - ((slice == this->NumSlices - 1) ? BackBit : 0) | ((col == 0) ? LeftBit : 0) | - ((col == this->NumColumns - 1) ? RightBit : 0) | ((row == 0) ? TopBit : 0) | - ((row == this->NumRows - 1) ? BottomBit : 0); + vtkm::Id3 pos = this->VertexPos(meshIndex); + vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) | + ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) | + ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0) | ((pos[2] == 0) ? FrontBit : 0) | + ((pos[2] == this->MeshSize[2] - 1) ? BackBit : 0); // in what follows, the boundary conditions always reset wasAscent // loop downwards so that we pick the same edges as previous versions @@ -289,13 +270,11 @@ public: // convert to a sort index vtkm::Id meshIndex = SortOrderPortal.Get(sortIndex); - vtkm::Id slice = this->VertexSlice(meshIndex); - vtkm::Id row = this->VertexRow(meshIndex); - vtkm::Id col = this->VertexColumn(meshIndex); - vtkm::Int8 boundaryConfig = ((slice == 0) ? FrontBit : 0) | - ((slice == this->NumSlices - 1) ? BackBit : 0) | ((col == 0) ? LeftBit : 0) | - ((col == this->NumColumns - 1) ? RightBit : 0) | ((row == 0) ? TopBit : 0) | - ((row == this->NumRows - 1) ? BottomBit : 0); + vtkm::Id3 pos = this->VertexPos(meshIndex); + vtkm::Int8 boundaryConfig = ((pos[0] == 0) ? LeftBit : 0) | + ((pos[0] == this->MeshSize[0] - 1) ? RightBit : 0) | ((pos[1] == 0) ? TopBit : 0) | + ((pos[1] == this->MeshSize[1] - 1) ? BottomBit : 0) | ((pos[2] == 0) ? FrontBit : 0) | + ((pos[2] == this->MeshSize[2] - 1) ? BackBit : 0); // Initialize "union find" int parentId[N_ALL_NEIGHBOURS]; diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ArcComparator.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ArcComparator.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ArcComparator.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ArcComparator.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CMakeLists.txt b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CMakeLists.txt similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CMakeLists.txt rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CMakeLists.txt diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedOtherStartIndexNNeighboursWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedOtherStartIndexNNeighboursWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedOtherStartIndexNNeighboursWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedOtherStartIndexNNeighboursWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h similarity index 98% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h index 3a212368a..915ac6517 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h @@ -65,7 +65,7 @@ #include #include -#include +#include namespace vtkm { diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedVector.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedVector.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedVector.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedVector.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedVectorDifferentFromNext.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedVectorDifferentFromNext.h similarity index 98% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedVectorDifferentFromNext.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedVectorDifferentFromNext.h index 3093917a7..4bf49ba55 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedVectorDifferentFromNext.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedVectorDifferentFromNext.h @@ -66,7 +66,7 @@ #include #include #include -#include +#include namespace vtkm { diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CompressNeighboursWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CompressNeighboursWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CompressNeighboursWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CompressNeighboursWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ComputeMaxNeighboursWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ComputeMaxNeighboursWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ComputeMaxNeighboursWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ComputeMaxNeighboursWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/FindStartIndexWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/FindStartIndexWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/FindStartIndexWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/FindStartIndexWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/InitToCombinedSortOrderArraysWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/InitToCombinedSortOrderArraysWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/InitToCombinedSortOrderArraysWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/InitToCombinedSortOrderArraysWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/MergeCombinedOtherStartIndexWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeCombinedOtherStartIndexWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/MergeCombinedOtherStartIndexWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeCombinedOtherStartIndexWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ReplaceArcNumWithToVertexWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ReplaceArcNumWithToVertexWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ReplaceArcNumWithToVertexWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ReplaceArcNumWithToVertexWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/SubtractAssignWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/SubtractAssignWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/SubtractAssignWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/SubtractAssignWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/UpdateCombinedNeighboursWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/UpdateCombinedNeighboursWorklet.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/UpdateCombinedNeighboursWorklet.h rename to vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/UpdateCombinedNeighboursWorklet.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/freudenthal_2D/Types.h b/vtkm/worklet/contourtree_augmented/meshtypes/freudenthal_2D/Types.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/freudenthal_2D/Types.h rename to vtkm/worklet/contourtree_augmented/meshtypes/freudenthal_2D/Types.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/freudenthal_3D/Types.h b/vtkm/worklet/contourtree_augmented/meshtypes/freudenthal_3D/Types.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/freudenthal_3D/Types.h rename to vtkm/worklet/contourtree_augmented/meshtypes/freudenthal_3D/Types.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/marchingcubes_3D/Types.h b/vtkm/worklet/contourtree_augmented/meshtypes/marchingcubes_3D/Types.h similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/marchingcubes_3D/Types.h rename to vtkm/worklet/contourtree_augmented/meshtypes/marchingcubes_3D/Types.h diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/CMakeLists.txt b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/CMakeLists.txt similarity index 100% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/CMakeLists.txt rename to vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/CMakeLists.txt diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary2D.h b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundary2D.h similarity index 87% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary2D.h rename to vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundary2D.h index 23e5dfd9a..29640dd6a 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary2D.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundary2D.h @@ -88,34 +88,34 @@ public: const InFieldPortalType sortIndicesPortal, const MeshBoundaryType& meshBoundary, vtkm::Id& boundaryVertex, - vtkm::Id& boundarySortIndex) + vtkm::Id& boundarySortIndex) const { auto meshStructure2D = meshBoundary.GetMeshStructure(); - vtkm::Id numBoundary = 2 * meshStructure2D.NumRows + 2 * meshStructure2D.NumColumns - 4; + vtkm::Id numBoundary = 2 * meshStructure2D.MeshSize[1] + 2 * meshStructure2D.MeshSize[0] - 4; + // For comments: [0] -> column, [1] -> row // Define the boundaryVertex result - if (boundaryId < meshStructure2D->NumColumns) + if (boundaryId < meshStructure2D.MeshSize[0]) { - boundaryVertex = meshStructure2D.VertexId(0, boundaryId); + boundaryVertex = meshStructure2D.VertexId(vtkm::Id2{ boundaryId, 0 }); } // then bottom row - else if (boundaryId > numBoundary - meshStructure2D.NumColumns - 1) + else if (boundaryId > numBoundary - meshStructure2D.MeshSize[0] - 1) { - boundaryVertex = meshStructure2D.VertexId( - meshStructure2D.NumRows - 1, boundaryId + meshStructure2D.NumColumns - numBoundary); + boundaryVertex = meshStructure2D.VertexId(vtkm::Id2{ + boundaryId + meshStructure2D.MeshSize[0] - numBoundary, meshStructure2D.MeshSize[1] - 1 }); } // then the row ends else { // row ends - vtkm::Id row = ((boundaryId - meshStructure2D.NumColumns) / 2) + 1; - vtkm::Id col = - ((boundaryId - meshStructure2D.NumColumns) % 2) ? (meshStructure2D.NumColumnsn - 1) : 0; - boundaryVertex = meshStructure2D.VertexId(row, col); + boundaryVertex = meshStructure2D.VertexId(vtkm::Id2{ + ((boundaryId - meshStructure2D.MeshSize[0]) % 2) ? (meshStructure2D.MeshSize[0] - 1) : 0, + ((boundaryId - meshStructure2D.MeshSize[0]) / 2) + 1 }); } // row ends // and fill in the sort index array as well boundarySortIndex = sortIndicesPortal.Get(boundaryVertex); - /* + /* TODO/FIXME: Delete this comment after code review and tests // compute how many elements are needed indexType nBoundary = 2 * nRows + 2 * nCols - 4; diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary3D.h b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundary3D.h similarity index 85% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary3D.h rename to vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundary3D.h index 4ece1ec69..f73871cbb 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary3D.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundary3D.h @@ -88,33 +88,32 @@ public: const InFieldPortalType sortIndicesPortal, const MeshBoundaryType& meshBoundary, vtkm::Id& boundaryVertex, - vtkm::Id& boundarySortIndex) + vtkm::Id& boundarySortIndex) const { auto meshStructure3D = meshBoundary.GetMeshStructure(); - vtkm::Id nRows = meshStructure3D.NumRows; - vtkm::Id nCols = meshStructure3D.NumCols; - vtkm::Id nSlices = meshStructure3D.NumSlices; + vtkm::Id3 meshSize = meshStructure3D.MeshSize; + // for comments [0]/x -> column, [1]/y -> row, [2]/z -> slice // calculate the number of boundary elements - all of the two xy faces - vtkm::Id nBoundary = 2 * nRows * nCols // xy faces - + 2 * nRows * (nSlices - 2) // yz faces - excluding vertices on xy - + 2 * (nCols - 2) * (nSlices - 2); // xz face interiors + vtkm::Id nBoundary = 2 * meshSize[1] * meshSize[0] // xy faces + + 2 * meshSize[1] * (meshSize[2] - 2) // yz faces - excluding vertices on xy + + 2 * (meshSize[0] - 2) * (meshSize[2] - 2); // xz face interiors - vtkm::Id row = 0, col = 0, slice = 0; - vtkm::Id sliceSize = nRows * nCols; - vtkm::Id sliceBoundarySize = 2 * nRows + 2 * nCols - 4; + vtkm::Id3 pos{ 0, 0, 0 }; + vtkm::Id sliceSize = meshSize[1] * meshSize[0]; + vtkm::Id sliceBoundarySize = 2 * meshSize[1] + 2 * meshSize[0] - 4; // do top plane first if (boundaryId < sliceSize) { // top plane - row = boundaryId / nCols; - col = boundaryId % nCols; - slice = 0; + pos[0] = boundaryId % meshSize[0]; + pos[1] = boundaryId / meshSize[0]; + pos[2] = 0; } // top plane // then bottom plane else if (boundaryId >= nBoundary - sliceSize) { // bottom plane - row = (boundaryId - (nBoundary - sliceSize)) / nCols; - col = (boundaryId - (nBoundary - sliceSize)) % nCols; - slice = nSlices - 1; + pos[0] = (boundaryId - (nBoundary - sliceSize)) % meshSize[0]; + pos[1] = (boundaryId - (nBoundary - sliceSize)) / meshSize[0]; + pos[2] = meshSize[2] - 1; } // bottom plane // now we have to deal with the exterior of the remaining slices else @@ -122,28 +121,28 @@ public: // first we subtract the size of the first slice vtkm::Id offsetBoundaryid = boundaryId - sliceSize; // now we can compute the slice id - slice = 1 + offsetBoundaryid / sliceBoundarySize; + pos[2] = 1 + offsetBoundaryid / sliceBoundarySize; // compute the local id on the slice - vtkm::Id sliceBoundaryid = offsetBoundaryid % sliceBoundarySize; - // now test for the first and last row - if (sliceBoundaryid < nCols) + vtkm::Id sliceBoundaryId = offsetBoundaryid % sliceBoundarySize; + // now test for the first and last pos[1] + if (sliceBoundaryId < meshSize[0]) { // first row - row = 0; - col = sliceBoundaryid; + pos[0] = sliceBoundaryId; + pos[1] = 0; } // first row - else if (sliceBoundaryid >= (sliceBoundarySize - nCols)) + else if (sliceBoundaryId >= (sliceBoundarySize - meshSize[0])) { // last row - row = nRows - 1; - col = sliceBoundaryid - (sliceBoundarySize - nCols); + pos[0] = sliceBoundaryId - (sliceBoundarySize - meshSize[0]); + pos[1] = meshSize[1] - 1; } // last row else { // any other row - row = ((sliceBoundaryid - nCols) / 2) + 1; - col = ((sliceBoundaryid - nCols) % 2) ? (nCols - 1) : 0; + pos[0] = ((sliceBoundaryId - meshSize[0]) % 2) ? (meshSize[0] - 1) : 0; + pos[1] = ((sliceBoundaryId - meshSize[0]) / 2) + 1; } // any other row } // slice exteriors // now we have row, col, slice all set, compute the actual ID - boundaryVertex = meshStructure3D.VertexId(slice, row, col); + boundaryVertex = meshStructure3D.VertexId(pos); // and fill in the index array as well boundarySortIndex = sortIndicesPortal.Get(boundaryVertex); diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h similarity index 96% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h rename to vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h index d69ad4b6b..e6c759393 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h @@ -81,12 +81,12 @@ public: VTKM_EXEC_CONT ComputeMeshBoundaryContourTreeMesh() {} - template + template VTKM_EXEC void operator()(const vtkm::Id& nodeIndex, const MeshBoundaryType& meshBoundary, - vtkm::Id& isOnBoundary) + bool& isOnBoundary) const { - isOnBoundary = meshBoundary.liesOnBoundary(nodeIndex); + isOnBoundary = meshBoundary.LiesOnBoundary(nodeIndex); /* indexVector isOnBoundary(globalMeshIndex.size()); for (indexType node = 0; node < globalMeshIndex.size(); node++) diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary2D.h b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundary2D.h similarity index 57% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary2D.h rename to vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundary2D.h index 972ea9059..6428ce5a8 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary2D.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundary2D.h @@ -62,7 +62,7 @@ #include #include -#include +#include #include @@ -79,55 +79,96 @@ class MeshBoundary2D { public: // Sort indicies types - using SortOrderPortalType = typename IdArrayType::template ExecutionTypes::PortalConst; + using SortIndicesPortalType = + typename IdArrayType::template ExecutionTypes::PortalConst; VTKM_EXEC_CONT MeshBoundary2D() - : MeshStructure(mesh_dem::MeshStructure2D(0, 0)) + : MeshStructure(0, 0) { } VTKM_CONT - MeshBoundary2D(vtkm::Id nrows, - vtkm::Id ncols, - const IdArrayType& sortOrder, - vtkm::cont::Token& token) - : MeshStructure(mesh_dem::MeshStructure2D(nrows, ncols)) + MeshBoundary2D(vtkm::Id2 meshSize, const IdArrayType& sortIndices, vtkm::cont::Token& token) + : MeshStructure(meshSize) { - this->SortOrderPortal = sortOrder.PrepareForInput(DeviceTag(), token); + this->SortIndicesPortal = sortIndices.PrepareForInput(DeviceTag(), token); } VTKM_EXEC_CONT - bool liesOnBoundary(const vtkm::Id index) const + bool LiesOnBoundary(const vtkm::Id meshIndex) const { - vtkm::Id meshSortOrderValue = this->SortOrderPortal.Get(index); - const vtkm::Id row = this->MeshStructure.VertexRow(meshSortOrderValue); - const vtkm::Id col = this->MeshStructure.VertexColumn(meshSortOrderValue); - - return (row == 0) || (col == 0) || (row == this->MeshStructure.NumRows - 1) || - (col == this->MeshStructure.NumColumns - 1); + const vtkm::Id2 pos{ this->MeshStructure.VertexPos(meshIndex) }; + return (pos[0] == 0) || (pos[1] == 0) || (pos[0] == this->MeshStructure.MeshSize[0] - 1) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1); } VTKM_EXEC_CONT - const mesh_dem::MeshStructure2D& GetMeshStructure() const + bool IsNecessary(const vtkm::Id meshIndex) const + { + vtkm::Id sortIndex = this->SortIndicesPortal.Get(meshIndex); + const vtkm::Id2 pos{ this->MeshStructure.VertexPos(meshIndex) }; + + // Keep only when lying on boundary + if ((pos[0] == 0) || (pos[1] == 0) || (pos[0] == this->MeshStructure.MeshSize[0] - 1) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1)) + { + // If vertex lies on boundary, keep all corners in any case + if (((pos[1] == 0) && ((pos[0] == 0) || (pos[0] == this->MeshStructure.MeshSize[0] - 1))) || + ((pos[1] == this->MeshStructure.MeshSize[1] - 1) && + ((pos[0] == 0) || (pos[0] == this->MeshStructure.MeshSize[0] - 1)))) + { + return true; + } + else + { + // if not a corner, keeep only vertices that are local extrema + vtkm::Id sp, sn; + if (pos[1] == 0 || pos[1] == this->MeshStructure.MeshSize[1] - 1) + { + assert(pos[0] > 0 && pos[0] < this->MeshStructure.MeshSize[0] - 1); + assert(meshIndex >= 1); + sp = this->SortIndicesPortal.Get(meshIndex - 1); + assert(meshIndex + 1 < this->SortIndicesPortal.GetNumberOfValues()); + sn = this->SortIndicesPortal.Get(meshIndex + 1); + } + else if (pos[0] == 0 || pos[0] == this->MeshStructure.MeshSize[0] - 1) + { + assert(pos[1] > 0 && pos[1] < this->MeshStructure.MeshSize[1] - 1); + assert(meshIndex >= this->MeshStructure.MeshSize[0]); + sp = this->SortIndicesPortal.Get(meshIndex - this->MeshStructure.MeshSize[0]); + assert(meshIndex + this->MeshStructure.MeshSize[0] < + this->SortIndices.GetNumberOfValues()); + sn = this->SortIndicesPortal.Get(meshIndex + this->MeshStructure.MeshSize[0]); + } + return (sortIndex < sp && sortIndex < sn) || (sortIndex > sp && sortIndex > sn); + } + } + else + { + // Discard vertices in the interior + return false; + } + } + VTKM_EXEC_CONT + const data_set_mesh::MeshStructure2D& GetMeshStructure() const { return this->MeshStructure; } private: // 2D Mesh size parameters - mesh_dem::MeshStructure2D MeshStructure; - SortOrderPortalType SortOrderPortal; + data_set_mesh::MeshStructure2D MeshStructure; + SortIndicesPortalType SortIndicesPortal; }; class MeshBoundary2DExec : public vtkm::cont::ExecutionObjectBase { public: VTKM_EXEC_CONT - MeshBoundary2DExec(vtkm::Id nrows, vtkm::Id ncols, const IdArrayType& inSortOrder) - : NumRows(nrows) - , NumColumns(ncols) - , SortOrder(inSortOrder) + MeshBoundary2DExec(vtkm::Id2 inMeshSize, const IdArrayType& inSortIndices) + : MeshSize(inMeshSize) + , SortIndices(inSortIndices) { } @@ -135,14 +176,13 @@ public: template MeshBoundary2D PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const { - return MeshBoundary2D(this->NumRows, this->NumColumns, this->SortOrder, token); + return MeshBoundary2D(this->MeshSize, this->SortIndices, token); } private: // 2D Mesh size parameters - vtkm::Id NumRows; - vtkm::Id NumColumns; - const IdArrayType& SortOrder; + vtkm::Id2 MeshSize; + const IdArrayType& SortIndices; }; diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundary3D.h b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundary3D.h new file mode 100644 index 000000000..c68b2f4fd --- /dev/null +++ b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundary3D.h @@ -0,0 +1,295 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +// Copyright (c) 2018, The Regents of the University of California, through +// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals +// from the U.S. Dept. of Energy). All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// (1) Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// (2) Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// (3) Neither the name of the University of California, Lawrence Berkeley National +// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. +// +//============================================================================= +// +// This code is an extension of the algorithm presented in the paper: +// Parallel Peak Pruning for Scalable SMP Contour Tree Computation. +// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens. +// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization +// (LDAV), October 2016, Baltimore, Maryland. +// +// The PPP2 algorithm and software were jointly developed by +// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and +// Oliver Ruebel (LBNL) +//============================================================================== + +// This header contains a collection of classes used to describe the boundary +// of a mesh, for each main mesh type (i.e., 2D, 3D, and ContourTreeMesh). +// For each mesh type, there are two classes, the actual boundary desriptor +// class and an ExectionObject class with the PrepareForInput function that +// VTKm expects to generate the object for the execution environment. + +#ifndef vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_3d_h +#define vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_3d_h + +#include + +#include +#include + +#include + +namespace vtkm +{ +namespace worklet +{ +namespace contourtree_augmented +{ + +template +class MeshBoundary3D : public vtkm::cont::ExecutionObjectBase +{ +public: + // Sort indicies types + using SortIndicesPortalType = + typename IdArrayType::template ExecutionTypes::PortalConst; + + VTKM_EXEC_CONT + MeshBoundary3D() + : MeshStructure(data_set_mesh::MeshStructure3D(vtkm::Id3{ 0, 0, 0 })) + { + } + + VTKM_CONT + MeshBoundary3D(vtkm::Id3 meshSize, const IdArrayType& inSortIndices, vtkm::cont::Token& token) + : MeshStructure(data_set_mesh::MeshStructure3D(meshSize)) + { + this->SortIndicesPortal = inSortIndices.PrepareForInput(DeviceTag(), token); + } + + VTKM_EXEC_CONT + bool LiesOnBoundary(const vtkm::Id meshIndex) const + { + const vtkm::Id3 pos = this->MeshStructure.VertexPos(meshIndex); + return (pos[0] == 0) || (pos[1] == 0) || (pos[2] == 0) || + (pos[0] == this->MeshStructure.MeshSize[0] - 1) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1) || + (pos[2] == this->MeshStructure.MeshSize[2] - 1); + } + + VTKM_EXEC_CONT + vtkm::Id CountLinkComponentsIn2DSlice(const vtkm::Id meshIndex, const vtkm::Id2 strides) const + { + // IMPORTANT: We assume that function is called only for *interior* vertices (i.e., neither row nor col + // within slice is 0 and we do not need to check for boundary cases). + vtkm::Id sortIndex = this->SortIndicesPortal.Get(meshIndex); + bool prevWasInUpperLink = false; + vtkm::Id numComponents = 0; + + const int N_INCIDENT_EDGES_2D = 6; + for (vtkm::Id edgeNo = 0; edgeNo < N_INCIDENT_EDGES_2D; edgeNo++) + { // per edge + VTKM_ASSERT(meshIndex + strides[1] + strides[0] < + this->SortIndicesPortal.GetNumberOfValues()); + VTKM_ASSERT(meshIndex - strides[1] - strides[0] >= 0); + vtkm::Id nbrSortIndex; + switch (edgeNo) + { + case 0: + nbrSortIndex = this->SortIndicesPortal.Get(meshIndex + strides[0]); + break; // [1] , [0] + 1 + case 1: + nbrSortIndex = this->SortIndicesPortal.Get(meshIndex + strides[1] + strides[0]); + break; // [1] + 1, [0] + 1 + case 2: + nbrSortIndex = this->SortIndicesPortal.Get(meshIndex + strides[1]); + break; // [1] + 1, [0] + case 3: + nbrSortIndex = this->SortIndicesPortal.Get(meshIndex - strides[0]); + break; // [1] , [0] - 1 + case 4: + nbrSortIndex = this->SortIndicesPortal.Get(meshIndex - strides[1] - strides[0]); + break; // [1] - 1, [0] - 1 + case 5: + nbrSortIndex = this->SortIndicesPortal.Get(meshIndex - strides[1]); + break; // [1] - 1, [0] + default: + std::abort(); + } + + bool currIsInUpperLink = (nbrSortIndex > sortIndex); + numComponents += (edgeNo != 0 && currIsInUpperLink != prevWasInUpperLink) ? 1 : 0; + } // per edge + return numComponents; + } + + VTKM_EXEC_CONT + bool IsNecessary(vtkm::Id meshIndex) const + { + vtkm::Id sortIndex = this->SortIndicesPortal.Get(meshIndex); + vtkm::Id3 pos{ this->MeshStructure.VertexPos(meshIndex) }; + vtkm::Id nPerSlice = this->MeshStructure.MeshSize[0] * + this->MeshStructure.MeshSize[1]; // number of vertices on a [2]-perpendicular "slice" + + // Keep only when lying on boundary + if ((pos[1] == 0) || (pos[0] == 0) || (pos[2] == 0) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1) || + (pos[0] == this->MeshStructure.MeshSize[0] - 1) || + (pos[2] == this->MeshStructure.MeshSize[2] - 1)) + { + // Keep data on corners + bool atEndOfLine = (pos[0] == 0) || (pos[0] == this->MeshStructure.MeshSize[0] - 1); + bool atQuadCorner = (pos[1] == 0 && atEndOfLine) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1 && atEndOfLine); + if ((pos[2] == 0 && atQuadCorner) || + (pos[2] == this->MeshStructure.MeshSize[2] - 1 && atQuadCorner)) + { + return true; + } + else + { + // Check if vertex lies along one of the boundary edges, if so, keep + // local extrema + // Edges in [0] direction + if ((pos[1] == 0 && pos[2] == 0) || + (pos[1] == 0 && pos[2] == this->MeshStructure.MeshSize[2] - 1) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1 && pos[2] == 0) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1 && + pos[2] == this->MeshStructure.MeshSize[2] - 1)) + { + VTKM_ASSERT(meshIndex >= 1); + vtkm::Id sp = this->SortIndicesPortal.Get(meshIndex - 1); + VTKM_ASSERT(meshIndex + 1 < this->SortIndicesPortal.GetNumberOfValues()); + vtkm::Id sn = this->SortIndicesPortal.Get(meshIndex + 1); + return (sortIndex < sp && sortIndex < sn) || (sortIndex > sp && sortIndex > sn); + } + // Edges in [1] directtion + else if ((pos[0] == 0 && pos[2] == 0) || + (pos[0] == 0 && pos[2] == this->MeshStructure.MeshSize[2] - 1) || + (pos[0] == this->MeshStructure.MeshSize[0] - 1 && pos[2] == 0) || + (pos[0] == this->MeshStructure.MeshSize[0] - 1 && + pos[2] == this->MeshStructure.MeshSize[2] - 1)) + { + VTKM_ASSERT(pos[1] > 0 && pos[1] < this->MeshStructure.MeshSize[1] - 1); + VTKM_ASSERT(meshIndex >= this->MeshStructure.MeshSize[0]); + vtkm::Id sp = this->SortIndicesPortal.Get(meshIndex - this->MeshStructure.MeshSize[0]); + VTKM_ASSERT(meshIndex + this->MeshStructure.MeshSize[0] < + this->SortIndicesPortal.GetNumberOfValues()); + vtkm::Id sn = this->SortIndicesPortal.Get(meshIndex + this->MeshStructure.MeshSize[0]); + return (sortIndex < sp && sortIndex < sn) || (sortIndex > sp && sortIndex > sn); + } + // Edges in [2] direction + else if ((pos[1] == 0 && pos[0] == 0) || + (pos[1] == 0 && pos[0] == this->MeshStructure.MeshSize[0] - 1) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1 && pos[0] == 0) || + (pos[1] == this->MeshStructure.MeshSize[1] - 1 && + pos[0] == this->MeshStructure.MeshSize[0] - 1)) + { + VTKM_ASSERT(meshIndex >= nPerSlice); + vtkm::Id sp = this->SortIndicesPortal.Get(meshIndex - nPerSlice); + VTKM_ASSERT(meshIndex + nPerSlice < this->SortIndicesPortal.GetNumberOfValues()); + vtkm::Id sn = this->SortIndicesPortal.Get(meshIndex + nPerSlice); + return (sortIndex < sp && sortIndex < sn) || (sortIndex > sp && sortIndex > sn); + } + else + { + // On a face/slice + if (pos[2] == 0 || pos[2] == this->MeshStructure.MeshSize[2] - 1) + { // On [2]-perpendicular face + VTKM_ASSERT(pos[0] != 0 && pos[0] != this->MeshStructure.MeshSize[0]); + VTKM_ASSERT(pos[1] != 0 && pos[1] != this->MeshStructure.MeshSize[1]); + return CountLinkComponentsIn2DSlice(meshIndex, this->MeshStructure.MeshSize[0], 1) == + 1; // FIXME: or != 2; + } + else if (pos[1] == 0 || pos[1] == this->MeshStructure.MeshSize[1] - 1) + { // On [1]-perpendicular face + VTKM_ASSERT(pos[0] != 0 && pos[0] != this->MeshStructure.MeshSize[0]); + VTKM_ASSERT(pos[2] != 0 && pos[2] != this->MeshStructure.MeshSize[2]); + return CountLinkComponentsIn2DSlice(meshIndex, nPerSlice, 1) == 1; // FIXME: or != 2; + } + else + { // On [0]-perpendicular face + VTKM_ASSERT(pos[0] == 0 || pos[0] == this->MeshStructure.MeshSize[0] - 1); + VTKM_ASSERT(pos[1] != 0 && pos[1] != this->MeshStructure.MeshSize[1]); + VTKM_ASSERT(pos[2] != 0 && pos[2] != this->MeshStructure.MeshSize[2]); + return CountLinkComponentsIn2DSlice( + meshIndex, this->MeshStructure.MeshSize[0], nPerSlice) == 1; // FIXME: or != 2; + } + } + } + } + else + { + return false; + } + } + + VTKM_EXEC_CONT + const data_set_mesh::MeshStructure3D& GetMeshStructure() const + { + return this->MeshStructure; + } + +protected: + // 3D Mesh size parameters + data_set_mesh::MeshStructure3D MeshStructure; + SortIndicesPortalType SortIndicesPortal; +}; + + +class MeshBoundary3DExec : public vtkm::cont::ExecutionObjectBase +{ +public: + VTKM_EXEC_CONT + MeshBoundary3DExec(vtkm::Id3 meshSize, const IdArrayType& inSortIndices) + : MeshSize(meshSize) + , SortIndices(inSortIndices) + { + } + + VTKM_CONT + template + MeshBoundary3D PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const + { + return MeshBoundary3D(this->MeshSize, this->SortIndices, token); + } + +protected: + // 3D Mesh size parameters + vtkm::Id3 MeshSize; + const IdArrayType& SortIndices; +}; + + +} // namespace contourtree_augmented +} // worklet +} // vtkm + +#endif diff --git a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h similarity index 80% rename from vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h rename to vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h index 831360797..0f968db8e 100644 --- a/vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h @@ -84,32 +84,35 @@ public: VTKM_CONT MeshBoundaryContourTreeMesh(const IdArrayType& globalMeshIndex, - vtkm::Id totalNRows, - vtkm::Id totalNCols, + vtkm::Id3 globalSize, vtkm::Id3 minIdx, vtkm::Id3 maxIdx, vtkm::cont::Token& token) - : TotalNRows(totalNRows) - , TotalNCols(totalNCols) + : GlobalSize(globalSize) , MinIdx(minIdx) , MaxIdx(maxIdx) { - assert(this->TotalNRows > 0 && this->TotalNCols > 0); + assert(this->GlobalSize[0] > 0 && this->GlobalSize[1] > 0); this->GlobalMeshIndexPortal = globalMeshIndex.PrepareForInput(DeviceTag(), token); } VTKM_EXEC_CONT - bool liesOnBoundary(const vtkm::Id index) const + bool LiesOnBoundary(const vtkm::Id index) const { - vtkm::Id idx = this->GlobalMeshIndexPortal.Get(index); - vtkm::Id3 rcs; - rcs[0] = vtkm::Id((idx % (this->TotalNRows * this->TotalNCols)) / this->TotalNCols); - rcs[1] = vtkm::Id(idx % this->TotalNCols); - rcs[2] = vtkm::Id(idx / (this->TotalNRows * this->TotalNCols)); - for (int d = 0; d < 3; ++d) + vtkm::Id global_idx = this->GlobalMeshIndexPortal.Get(index); + vtkm::Id3 mesh_idx{ vtkm::Id(global_idx % this->GlobalSize[0]), + vtkm::Id((global_idx % (this->GlobalSize[0] * this->GlobalSize[1])) / + this->GlobalSize[0]), + vtkm::Id(global_idx / (this->GlobalSize[0] * this->GlobalSize[1])) }; + + // FIXME: Probably better communicate n_dims in constructor or make it a template parameter + // Or at least be more consistent in setting this in MinIdx/MaxIdx. Currently MinIdx[2] is 0 + // and MaxIdx[2] is -1 for a 2D data set. + const auto n_dims = (MaxIdx[2] == -1) ? 2 : 3; + for (int d = 0; d < n_dims; ++d) { if (this->MinIdx[d] != this->MaxIdx[d] && - (rcs[d] == this->MinIdx[d] || rcs[d] == this->MaxIdx[d])) + (mesh_idx[d] == this->MinIdx[d] || mesh_idx[d] == this->MaxIdx[d])) { return true; } @@ -117,10 +120,12 @@ public: return false; } + VTKM_EXEC_CONT + bool IsNecessary(const vtkm::Id idx) const { return this->LiesOnBoundary(idx); } + private: // mesh block parameters - vtkm::Id TotalNRows; - vtkm::Id TotalNCols; + vtkm::Id3 GlobalSize; vtkm::Id3 MinIdx; vtkm::Id3 MaxIdx; IndicesPortalType GlobalMeshIndexPortal; @@ -132,13 +137,11 @@ class MeshBoundaryContourTreeMeshExec : public vtkm::cont::ExecutionObjectBase public: VTKM_EXEC_CONT MeshBoundaryContourTreeMeshExec(const IdArrayType& globalMeshIndex, - vtkm::Id totalNRows, - vtkm::Id totalNCols, + vtkm::Id3 globalSize, vtkm::Id3 minIdx, vtkm::Id3 maxIdx) : GlobalMeshIndex(globalMeshIndex) - , TotalNRows(totalNRows) - , TotalNCols(totalNCols) + , GlobalSize(globalSize) , MinIdx(minIdx) , MaxIdx(maxIdx) { @@ -150,13 +153,12 @@ public: vtkm::cont::Token& token) const { return MeshBoundaryContourTreeMesh( - this->GlobalMeshIndex, this->TotalNRows, this->TotalNCols, this->MinIdx, this->MaxIdx, token); + this->GlobalMeshIndex, this->GlobalSize, this->MinIdx, this->MaxIdx, token); } private: const IdArrayType& GlobalMeshIndex; - vtkm::Id TotalNRows; - vtkm::Id TotalNCols; + vtkm::Id3 GlobalSize; vtkm::Id3 MinIdx; vtkm::Id3 MaxIdx; }; diff --git a/vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h b/vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h index 42d9ed7de..80cf076f2 100644 --- a/vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h +++ b/vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h @@ -54,6 +54,7 @@ #define vtk_m_worklet_contourtree_distributed_mergeblockfunctor_h #include +#include #include // clang-format off @@ -117,7 +118,8 @@ void MergeBlockFunctor( // Construct the two contour tree mesh by assignign the block data vtkm::worklet::contourtree_augmented::ContourTreeMesh contourTreeMeshIn; contourTreeMeshIn.NumVertices = recvblock.NumVertices; - contourTreeMeshIn.SortOrder = recvblock.SortOrder; + contourTreeMeshIn.SortOrder = vtkm::cont::ArrayHandleIndex(contourTreeMeshIn.NumVertices); + contourTreeMeshIn.SortIndices = vtkm::cont::ArrayHandleIndex(contourTreeMeshIn.NumVertices); contourTreeMeshIn.SortedValues = recvblock.SortedValue; contourTreeMeshIn.GlobalMeshIndex = recvblock.GlobalMeshIndex; contourTreeMeshIn.Neighbours = recvblock.Neighbours; @@ -126,7 +128,8 @@ void MergeBlockFunctor( vtkm::worklet::contourtree_augmented::ContourTreeMesh contourTreeMeshOut; contourTreeMeshOut.NumVertices = block->NumVertices; - contourTreeMeshOut.SortOrder = block->SortOrder; + contourTreeMeshOut.SortOrder = vtkm::cont::ArrayHandleIndex(contourTreeMeshOut.NumVertices); + contourTreeMeshOut.SortIndices = vtkm::cont::ArrayHandleIndex(contourTreeMeshOut.NumVertices); contourTreeMeshOut.SortedValues = block->SortedValue; contourTreeMeshOut.GlobalMeshIndex = block->GlobalMeshIndex; contourTreeMeshOut.Neighbours = block->Neighbours; @@ -158,7 +161,6 @@ void MergeBlockFunctor( { // Save the data from our block for the next iteration block->NumVertices = contourTreeMeshOut.NumVertices; - block->SortOrder = contourTreeMeshOut.SortOrder; block->SortedValue = contourTreeMeshOut.SortedValues; block->GlobalMeshIndex = contourTreeMeshOut.GlobalMeshIndex; block->Neighbours = contourTreeMeshOut.Neighbours; @@ -180,11 +182,7 @@ void MergeBlockFunctor( currBlockOrigin[1] + currBlockSize[1] - 1, currBlockOrigin[2] + currBlockSize[2] - 1); auto meshBoundaryExecObj = - contourTreeMeshOut.GetMeshBoundaryExecutionObject(globalSize[0], // totalNRows - globalSize[1], // totalNCols - currBlockOrigin, // minIdx - maxIdx // maxIdx - ); + contourTreeMeshOut.GetMeshBoundaryExecutionObject(globalSize, currBlockOrigin, maxIdx); worklet.Run( contourTreeMeshOut.SortedValues, // Unused param. Provide something to keep the API happy contourTreeMeshOut, @@ -215,7 +213,6 @@ void MergeBlockFunctor( // Copy the data from newContourTreeMesh into block block->NumVertices = newContourTreeMesh->NumVertices; - block->SortOrder = newContourTreeMesh->SortOrder; block->SortedValue = newContourTreeMesh->SortedValues; block->GlobalMeshIndex = newContourTreeMesh->GlobalMeshIndex; block->Neighbours = newContourTreeMesh->Neighbours; diff --git a/vtkm/worklet/contourtree_distributed/MultiBlockContourTreeHelper.h b/vtkm/worklet/contourtree_distributed/MultiBlockContourTreeHelper.h index 6c80935cb..baa1b670f 100644 --- a/vtkm/worklet/contourtree_distributed/MultiBlockContourTreeHelper.h +++ b/vtkm/worklet/contourtree_distributed/MultiBlockContourTreeHelper.h @@ -56,7 +56,7 @@ #include #include -#include +#include #include #include @@ -64,7 +64,7 @@ //#include #include #include -#include +#include namespace vtkm @@ -153,13 +153,6 @@ public: unsigned int computeRegularStructure) { - vtkm::Id startRow = localBlockOrigin[0]; - vtkm::Id startCol = localBlockOrigin[1]; - vtkm::Id startSlice = localBlockOrigin[2]; - vtkm::Id numRows = localBlockSize[0]; - vtkm::Id numCols = localBlockSize[1]; - vtkm::Id totalNumRows = globalSize[0]; - vtkm::Id totalNumCols = globalSize[1]; // compute the global mesh index and initalize the local contour tree mesh if (computeRegularStructure == 1) { @@ -170,7 +163,7 @@ public: vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler>( sortOrder, vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler( - startRow, startCol, startSlice, numRows, numCols, totalNumRows, totalNumCols)); + localBlockOrigin, localBlockSize, globalSize)); vtkm::cont::Algorithm::Copy(transformedIndex, localGlobalMeshIndex); // Compute the local contour tree mesh auto localContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh( @@ -190,7 +183,7 @@ public: auto transformedIndex = vtkm::cont::make_ArrayHandleTransform( permutedSortOrder, vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler( - startRow, startCol, startSlice, numRows, numCols, totalNumRows, totalNumCols)); + localBlockOrigin, localBlockSize, globalSize)); vtkm::cont::Algorithm::Copy(transformedIndex, localGlobalMeshIndex); // Compute the local contour tree mesh auto localContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh( diff --git a/vtkm/worklet/testing/UnitTestContourTreeUniformAugmented.cxx b/vtkm/worklet/testing/UnitTestContourTreeUniformAugmented.cxx index 0df680fa0..79f6dcad5 100644 --- a/vtkm/worklet/testing/UnitTestContourTreeUniformAugmented.cxx +++ b/vtkm/worklet/testing/UnitTestContourTreeUniformAugmented.cxx @@ -310,19 +310,17 @@ private: template void CallTestContourTreeAugmentedSteps( const vtkm::cont::ArrayHandle fieldArray, - const vtkm::Id nRows, - const vtkm::Id nCols, - const vtkm::Id nSlices, + const vtkm::Id3 meshSize, bool useMarchingCubes, unsigned int computeRegularStructure, ExpectedStepResults& expectedResults) const { using namespace vtkm::worklet::contourtree_augmented; // 2D Contour Tree - if (nSlices == 1) + if (meshSize[2] == 1) { // Build the mesh and fill in the values - Mesh_DEM_Triangulation_2D_Freudenthal mesh(nRows, nCols); + DataSetMeshTriangulation2DFreudenthal mesh(vtkm::Id2{ meshSize[0], meshSize[1] }); // Run the contour tree on the mesh RunTestContourTreeAugmentedSteps(fieldArray, mesh, @@ -335,7 +333,7 @@ private: else if (useMarchingCubes) { // Build the mesh and fill in the values - Mesh_DEM_Triangulation_3D_MarchingCubes mesh(nRows, nCols, nSlices); + DataSetMeshTriangulation3DMarchingCubes mesh(meshSize); // Run the contour tree on the mesh RunTestContourTreeAugmentedSteps(fieldArray, mesh, @@ -348,7 +346,7 @@ private: else { // Build the mesh and fill in the values - Mesh_DEM_Triangulation_3D_Freudenthal mesh(nRows, nCols, nSlices); + DataSetMeshTriangulation3DFreudenthal mesh(meshSize); // Run the contour tree on the mesh RunTestContourTreeAugmentedSteps(fieldArray, mesh, @@ -377,16 +375,13 @@ private: dataSet.GetCellSet().CopyTo(cellSet); vtkm::Id3 pointDimensions = cellSet.GetPointDimensions(); - vtkm::Id nRows = pointDimensions[0]; - vtkm::Id nCols = pointDimensions[1]; - vtkm::Id nSlices = pointDimensions[2]; vtkm::cont::ArrayHandle field; dataSet.GetField("pointvar").GetData().CopyTo(field); // Run the specific test CallTestContourTreeAugmentedSteps( - field, nRows, nCols, nSlices, useMarchingCubes, computeRegularStructure, expectedResults); + field, pointDimensions, useMarchingCubes, computeRegularStructure, expectedResults); } /// @@ -727,10 +722,8 @@ public: vtkm::cont::CellSetStructured<2> cellSet; dataSet.GetCellSet().CopyTo(cellSet); - vtkm::Id2 pointDimensions = cellSet.GetPointDimensions(); - vtkm::Id nRows = pointDimensions[0]; - vtkm::Id nCols = pointDimensions[1]; - vtkm::Id nSlices = 1; + vtkm::Id2 pointDimensions2D = cellSet.GetPointDimensions(); + vtkm::Id3 meshSize{ pointDimensions2D[0], pointDimensions2D[1], 1 }; vtkm::cont::ArrayHandle field; dataSet.GetField("pointvar").GetData().CopyTo(field); @@ -747,9 +740,7 @@ public: contourTree, meshSortOrder, numIterations, - nRows, - nCols, - nSlices, + meshSize, useMarchingCubes, computeRegularStructure); @@ -799,9 +790,6 @@ public: dataSet.GetCellSet().CopyTo(cellSet); vtkm::Id3 pointDimensions = cellSet.GetPointDimensions(); - vtkm::Id nRows = pointDimensions[0]; - vtkm::Id nCols = pointDimensions[1]; - vtkm::Id nSlices = pointDimensions[2]; vtkm::cont::ArrayHandle field; dataSet.GetField("pointvar").GetData().CopyTo(field); @@ -818,9 +806,7 @@ public: contourTree, meshSortOrder, numIterations, - nRows, - nCols, - nSlices, + pointDimensions, useMarchingCubes, computeRegularStructure); @@ -877,9 +863,6 @@ public: dataSet.GetCellSet().CopyTo(cellSet); vtkm::Id3 pointDimensions = cellSet.GetPointDimensions(); - vtkm::Id nRows = pointDimensions[0]; - vtkm::Id nCols = pointDimensions[1]; - vtkm::Id nSlices = pointDimensions[2]; vtkm::cont::ArrayHandle field; dataSet.GetField("pointvar").GetData().CopyTo(field); @@ -896,9 +879,7 @@ public: contourTree, meshSortOrder, numIterations, - nRows, - nCols, - nSlices, + pointDimensions, useMarchingCubes, computeRegularStructure); From 8489a69c399bdd3851ee4832f20d5261b2e085e7 Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Tue, 15 Sep 2020 12:55:24 -0700 Subject: [PATCH 35/51] Fixed missing invoker compile error --- .../DataSetMeshTriangulation2DFreudenthal.h | 15 ++++++++------- .../DataSetMeshTriangulation3DFreudenthal.h | 15 ++++++++------- .../DataSetMeshTriangulation3DMarchingCubes.h | 15 ++++++++------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation2DFreudenthal.h b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation2DFreudenthal.h index 50d4fc365..6b6b72ffa 100644 --- a/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation2DFreudenthal.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation2DFreudenthal.h @@ -145,13 +145,14 @@ void DataSetMeshTriangulation2DFreudenthal::GetBoundaryVertices( vtkm::Id numBoundary = 2 * this->MeshSize[1] + 2 * this->MeshSize[0] - 4; auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary); ComputeMeshBoundary2D computeMeshBoundary2dWorklet; - this->Invoke(computeMeshBoundary2dWorklet, - boundaryId, // input - this->SortIndices, // input - (meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject() - : *meshBoundaryExecObj, // input - boundaryVertexArray, // output - boundarySortIndexArray // output + vtkm::cont::Invoker invoke; + invoke(computeMeshBoundary2dWorklet, + boundaryId, // input + this->SortIndices, // input + (meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject() + : *meshBoundaryExecObj, // input + boundaryVertexArray, // output + boundarySortIndexArray // output ); } diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DFreudenthal.h b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DFreudenthal.h index bdb2d6032..59b02e6f1 100644 --- a/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DFreudenthal.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DFreudenthal.h @@ -161,13 +161,14 @@ void DataSetMeshTriangulation3DFreudenthal::GetBoundaryVertices( + 2 * (this->MeshSize[0] - 2) * (this->MeshSize[2] - 2); // xz face interiors auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary); ComputeMeshBoundary3D computeMeshBoundary3dWorklet; - this->Invoke(computeMeshBoundary3dWorklet, - boundaryId, // input - this->SortIndices, // input - (meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject() - : *meshBoundaryExecObj, // input - boundaryVertexArray, // output - boundarySortIndexArray // output + vtkm::cont::Invoker invoke; + invoke(computeMeshBoundary3dWorklet, + boundaryId, // input + this->SortIndices, // input + (meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject() + : *meshBoundaryExecObj, // input + boundaryVertexArray, // output + boundarySortIndexArray // output ); } diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DMarchingCubes.h b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DMarchingCubes.h index 7dec2fd73..bb2e71ba0 100644 --- a/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DMarchingCubes.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/DataSetMeshTriangulation3DMarchingCubes.h @@ -194,13 +194,14 @@ void DataSetMeshTriangulation3DMarchingCubes::GetBoundaryVertices( + 2 * (this->MeshSize[0] - 2) * (this->MeshSize[2] - 2); // xz face interiors auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary); ComputeMeshBoundary3D computeMeshBoundary3dWorklet; - this->Invoke(computeMeshBoundary3dWorklet, - boundaryId, // input - this->SortIndices, // input - (meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject() - : *meshBoundaryExecObj, // input - boundaryVertexArray, // output - boundarySortIndexArray // output + vtkm::cont::Invoker invoke; + invoke(computeMeshBoundary3dWorklet, + boundaryId, // input + this->SortIndices, // input + (meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject() + : *meshBoundaryExecObj, // input + boundaryVertexArray, // output + boundarySortIndexArray // output ); } From af697e4527d006964e0365cfad31ec57eb9bf80e Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Tue, 15 Sep 2020 13:46:11 -0700 Subject: [PATCH 36/51] Use std::swap instead of manual swap --- examples/contour_tree_augmented/ContourTreeApp.cxx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/contour_tree_augmented/ContourTreeApp.cxx b/examples/contour_tree_augmented/ContourTreeApp.cxx index a6bf6e515..5b947e8e8 100644 --- a/examples/contour_tree_augmented/ContourTreeApp.cxx +++ b/examples/contour_tree_augmented/ContourTreeApp.cxx @@ -514,11 +514,7 @@ int main(int argc, char* argv[]) prevTime = currTime; // swap dims order - { - vtkm::Id temp = dims[0]; - dims[0] = dims[1]; - dims[1] = temp; - } + std::swap(dims[0], dims[1]); #ifndef WITH_MPI // We only need the inDataSet if are not using MPI otherwise we'll constructe a multi-block dataset // build the input dataset From b6343c049c22813968143ce60edfd5de9eefc50e Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Wed, 16 Sep 2020 12:04:31 -0700 Subject: [PATCH 37/51] Applied Ken Moreland's suggested fix to avoid copy --- .../contourtree_augmented/ContourTreeMaker.h | 27 ++++++++----------- .../ComputeRegularStructure_LocateSuperarcs.h | 26 ++++++++---------- 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h b/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h index 758f5b121..f575c4bb9 100644 --- a/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h +++ b/vtkm/worklet/contourtree_augmented/ContourTreeMaker.h @@ -534,26 +534,21 @@ void ContourTreeMaker::ComputeBoundaryRegularStructure( // for (indexType supernode = 0; supernode < this->ContourTreeResult.Supernodes.size(); supernode++) // superparents[this->ContourTreeResult.Supernodes[supernode]] = supernode; - IdArrayType sortOrder; // TODO/FIX: Why is this copy necessary? - vtkm::cont::Algorithm::Copy(mesh.SortOrder, sortOrder); - // Second step - for all remaining (regular) nodes, locate the superarc to which they belong contourtree_maker_inc_ns::ComputeRegularStructure_LocateSuperarcsOnBoundary locateSuperarcsOnBoundaryWorklet(this->ContourTreeResult.Hypernodes.GetNumberOfValues(), this->ContourTreeResult.Supernodes.GetNumberOfValues()); - this->Invoke( - locateSuperarcsOnBoundaryWorklet, - superparents, // (input/output) - this->ContourTreeResult.WhenTransferred, // (input) - this->ContourTreeResult.Hyperparents, // (input) - this->ContourTreeResult.Hyperarcs, // (input) - this->ContourTreeResult.Hypernodes, // (input) - this->ContourTreeResult.Supernodes, // (input) - meshExtrema.Peaks, // (input) - meshExtrema.Pits, // (input) - sortOrder, // (input) - //mesh.SortOrder, // (input) // TODO/FIXME: Why can't I just pass this? - meshBoundaryExecObj); // (input) + this->Invoke(locateSuperarcsOnBoundaryWorklet, + superparents, // (input/output) + this->ContourTreeResult.WhenTransferred, // (input) + this->ContourTreeResult.Hyperparents, // (input) + this->ContourTreeResult.Hyperarcs, // (input) + this->ContourTreeResult.Hypernodes, // (input) + this->ContourTreeResult.Supernodes, // (input) + meshExtrema.Peaks, // (input) + meshExtrema.Pits, // (input) + mesh.SortOrder, // (input) + meshBoundaryExecObj); // (input) // We have now set the superparent correctly for each node, and need to sort them to get the correct regular arcs // DAVID "ContourTreeMaker.h" line 338 diff --git a/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h b/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h index c32bd1b16..598463de0 100644 --- a/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h +++ b/vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h @@ -76,8 +76,8 @@ public: WholeArrayIn contourTreeHyperarcs, // (input) WholeArrayIn contourTreeHypernodes, // (input) WholeArrayIn contourTreeSupernodes, // (input) - WholeArrayIn meshExtremaPeaks, // (input) - WholeArrayIn meshExtremaPits); // (input) + FieldIn meshExtremaPeaks, // (input) + FieldIn meshExtremaPits); // (input) typedef void ExecutionSignature(_1, InputIndex, _2, _3, _4, _5, _6, _7, _8); using InputDomain = _1; @@ -101,16 +101,14 @@ public: const InFieldPortalType& contourTreeHyperarcsPortal, const InFieldPortalType& contourTreeHypernodesPortal, const InFieldPortalType& contourTreeSupernodesPortal, - const InFieldPortalType& meshExtremaPeaksPortal, - const InFieldPortalType& meshExtremaPitsPortal) const + vtkm::Id top, + vtkm::Id bottom) const { // per node // if the superparent is already set, it's a supernode, so skip it. if (NoSuchElement(contourTreeSuperparentsPortal.Get(node))) { // regular nodes only // we will need to prune top and bottom until one of them prunes past the node - vtkm::Id top = meshExtremaPeaksPortal.Get(node); - vtkm::Id bottom = meshExtremaPitsPortal.Get(node); // these are the regular IDs of supernodes, so their superparents are already set vtkm::Id topSuperparent = contourTreeSuperparentsPortal.Get(MaskedIndex(top)); vtkm::Id bottomSuperparent = contourTreeSuperparentsPortal.Get(MaskedIndex(bottom)); @@ -413,9 +411,9 @@ public: WholeArrayIn contourTreeHyperarcs, // (input) WholeArrayIn contourTreeHypernodes, // (input) WholeArrayIn contourTreeSupernodes, // (input) - WholeArrayIn meshExtremaPeaks, // (input) - WholeArrayIn meshExtremaPits, // (input) - WholeArrayIn sortOrder, // (input) + FieldIn meshExtremaPeaks, // (input) + FieldIn meshExtremaPits, // (input) + FieldIn sortOrder, // (input) ExecObject meshBoundary); // (input) typedef void ExecutionSignature(_1, InputIndex, _2, _3, _4, _5, _6, _7, _8, _9, _10); @@ -440,19 +438,17 @@ public: const InFieldPortalType& contourTreeHyperarcsPortal, const InFieldPortalType& contourTreeHypernodesPortal, const InFieldPortalType& contourTreeSupernodesPortal, - const InFieldPortalType& meshExtremaPeaksPortal, - const InFieldPortalType& meshExtremaPitsPortal, - const InFieldPortalType& sortOrderPortal, + vtkm::Id top, + vtkm::Id bottom, + vtkm::Id sortOrder, const MeshBoundaryType& meshBoundary) const { // per node // if the superparent is already set, it's a supernode, so skip it. if (NoSuchElement(contourTreeSuperparentsPortal.Get(node)) && - meshBoundary.LiesOnBoundary(sortOrderPortal.Get(node))) + meshBoundary.LiesOnBoundary(sortOrder)) { // regular nodes only // we will need to prune top and bottom until one of them prunes past the node - vtkm::Id top = meshExtremaPeaksPortal.Get(node); - vtkm::Id bottom = meshExtremaPitsPortal.Get(node); // these are the regular IDs of supernodes, so their superparents are already set vtkm::Id topSuperparent = contourTreeSuperparentsPortal.Get(MaskedIndex(top)); vtkm::Id bottomSuperparent = contourTreeSuperparentsPortal.Get(MaskedIndex(bottom)); From b443fb500e081589086a1766033d294ea6c94bce Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Wed, 16 Sep 2020 12:35:20 -0700 Subject: [PATCH 38/51] Added note for future reference during API refactoring --- vtkm/worklet/ContourTreeUniformAugmented.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vtkm/worklet/ContourTreeUniformAugmented.h b/vtkm/worklet/ContourTreeUniformAugmented.h index f5e67a0eb..c3932b723 100644 --- a/vtkm/worklet/ContourTreeUniformAugmented.h +++ b/vtkm/worklet/ContourTreeUniformAugmented.h @@ -357,8 +357,9 @@ private: nIterations = treeMaker.ContourTreeResult.NumIterations; // Need to make a copy of sortOrder since ContourTreeMesh uses a smart array handle // TODO: Check if we can just make sortOrder a return array with variable type or if we can make the SortOrder return optional + // TODO/FIXME: According to Ken Moreland the short answer is no. We may need to go back and refactor this when we + // improve the contour tree API. https://gitlab.kitware.com/vtk/vtk-m/-/merge_requests/2263#note_831128 for more details. vtkm::cont::Algorithm::Copy(mesh.SortOrder, sortOrder); - // sortOrder = mesh.SortOrder; // ProcessContourTree::CollectSortedSuperarcs(contourTree, mesh.SortOrder, saddlePeak); // contourTree.SortedArcPrint(mesh.SortOrder); // contourTree.PrintDotSuperStructure(); From 33a7f5610dec3fcbb0a2bb5bb85a492bc3e82457 Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Wed, 16 Sep 2020 12:35:49 -0700 Subject: [PATCH 39/51] Added missing this-> for data members --- vtkm/worklet/contourtree_augmented/DataSetMesh.h | 4 ++-- .../data_set_mesh/IdRelabeler.h | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/vtkm/worklet/contourtree_augmented/DataSetMesh.h b/vtkm/worklet/contourtree_augmented/DataSetMesh.h index 39d929d14..05120e64c 100644 --- a/vtkm/worklet/contourtree_augmented/DataSetMesh.h +++ b/vtkm/worklet/contourtree_augmented/DataSetMesh.h @@ -205,8 +205,8 @@ void DataSetMesh::SortData(const vtkm::cont::ArrayHandle& values this->SortOrder.ReleaseResources(); // allocate memory for the sort arrays - SortOrder.Allocate(this->NumVertices); - SortIndices.Allocate(this->NumVertices); + this->SortOrder.Allocate(this->NumVertices); + this->SortIndices.Allocate(this->NumVertices); // now sort the sort order vector by the values, i.e,. initialize the SortOrder member variable vtkm::cont::ArrayHandleIndex initVertexIds( diff --git a/vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h b/vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h index 0dda9a077..3375003c1 100644 --- a/vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h +++ b/vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h @@ -99,13 +99,15 @@ public: vtkm::Id operator()(vtkm::Id v) const { // Translate v into mesh coordinates and add offset - vtkm::Id3 pos{ LocalBlockOrigin[0] + (v % LocalBlockSize[0]), - LocalBlockOrigin[1] + - (v % (LocalBlockSize[1] * LocalBlockSize[0]) / LocalBlockSize[0]), - LocalBlockOrigin[2] + (v / (LocalBlockSize[1] * LocalBlockSize[0])) }; + vtkm::Id3 pos{ + this->LocalBlockOrigin[0] + (v % this->LocalBlockSize[0]), + this->LocalBlockOrigin[1] + + (v % (this->LocalBlockSize[1] * this->LocalBlockSize[0]) / this->LocalBlockSize[0]), + this->LocalBlockOrigin[2] + (v / (this->LocalBlockSize[1] * this->LocalBlockSize[0])) + }; // Translate mesh coordinates into global Id - return (pos[2] * GlobalSize[1] + pos[1]) * GlobalSize[0] + pos[0]; + return (pos[2] * this->GlobalSize[1] + pos[1]) * this->GlobalSize[0] + pos[0]; } private: From edd71539c98ca85029dadd2d284f9f9db59aa7b8 Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Thu, 17 Sep 2020 05:39:14 -0700 Subject: [PATCH 40/51] Fix compile error due to renamed includes --- .../BoundaryRestrictedAugmentedContourTree.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vtkm/worklet/contourtree_distributed/BoundaryRestrictedAugmentedContourTree.h b/vtkm/worklet/contourtree_distributed/BoundaryRestrictedAugmentedContourTree.h index 9809836c5..51a912021 100644 --- a/vtkm/worklet/contourtree_distributed/BoundaryRestrictedAugmentedContourTree.h +++ b/vtkm/worklet/contourtree_distributed/BoundaryRestrictedAugmentedContourTree.h @@ -56,8 +56,8 @@ #include #include #include -#include -#include +#include +#include #include #include From ce0aa1cf94f9cc254136b48fa9e43f42d6b689b0 Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Thu, 17 Sep 2020 05:42:41 -0700 Subject: [PATCH 41/51] Fix compile errors --- vtkm/filter/ContourTreeUniformDistributed.hxx | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/vtkm/filter/ContourTreeUniformDistributed.hxx b/vtkm/filter/ContourTreeUniformDistributed.hxx index 3468650f1..0fe78fef5 100644 --- a/vtkm/filter/ContourTreeUniformDistributed.hxx +++ b/vtkm/filter/ContourTreeUniformDistributed.hxx @@ -59,7 +59,7 @@ // single-node augmented contour tree includes #include #include -#include +#include // distributed contour tree includes #include @@ -105,7 +105,7 @@ struct PostExecuteCaller //----------------------------------------------------------------------------- ContourTreeUniformDistributed::ContourTreeUniformDistributed(bool useMarchingCubes) - : vtkm::filter::FilterCell() + : vtkm::filter::FilterField() , UseMarchingCubes(useMarchingCubes) , MultiBlockTreeHelper(nullptr) { @@ -146,14 +146,11 @@ vtkm::cont::DataSet ContourTreeUniformDistributed::DoExecute( throw vtkm::cont::ErrorFilterExecution("Point field expected."); } - // Use the GetRowsColsSlices struct defined in the header to collect the nRows, nCols, and nSlices information - vtkm::worklet::ContourTreeAugmented worklet; - vtkm::Id nRows; - vtkm::Id nCols; - vtkm::Id nSlices = 1; + // Get mesh size + vtkm::Id3 meshSize; const auto& cells = input.GetCellSet(); vtkm::filter::ApplyPolicyCellSet(cells, policy, *this) - .CastAndCall(vtkm::worklet::contourtree_augmented::GetRowsColsSlices(), nRows, nCols, nSlices); + .CastAndCall(vtkm::worklet::contourtree_augmented::GetPointDimensions(), meshSize); // TODO blockIndex needs to change if we have multiple blocks per MPI rank and DoExecute is called for multiple blocks std::size_t blockIndex = 0; @@ -161,15 +158,14 @@ vtkm::cont::DataSet ContourTreeUniformDistributed::DoExecute( unsigned int compRegularStruct = 1; // Run the worklet + vtkm::worklet::ContourTreeAugmented worklet; worklet.Run(field, MultiBlockTreeHelper ? MultiBlockTreeHelper->LocalContourTrees[blockIndex] : this->ContourTreeData, MultiBlockTreeHelper ? MultiBlockTreeHelper->LocalSortOrders[blockIndex] : this->MeshSortOrder, this->NumIterations, - nRows, - nCols, - nSlices, + meshSize, this->UseMarchingCubes, compRegularStruct); @@ -281,7 +277,8 @@ VTKM_CONT void ContourTreeUniformDistributed::DoPostExecute( // create the local data block structure localDataBlocks[bi] = new vtkm::worklet::contourtree_distributed::ContourTreeBlockData(); localDataBlocks[bi]->NumVertices = currContourTreeMesh->NumVertices; - localDataBlocks[bi]->SortOrder = currContourTreeMesh->SortOrder; + // FIXME: Commented out to avoid compile error, full fix to follow in subsequent merge request + // localDataBlocks[bi]->SortOrder = currContourTreeMesh->SortOrder; localDataBlocks[bi]->SortedValue = currContourTreeMesh->SortedValues; localDataBlocks[bi]->GlobalMeshIndex = currContourTreeMesh->GlobalMeshIndex; localDataBlocks[bi]->Neighbours = currContourTreeMesh->Neighbours; @@ -377,7 +374,8 @@ VTKM_CONT void ContourTreeUniformDistributed::DoPostExecute( // Construct the contour tree mesh from the last block vtkm::worklet::contourtree_augmented::ContourTreeMesh contourTreeMeshOut; contourTreeMeshOut.NumVertices = localDataBlocks[0]->NumVertices; - contourTreeMeshOut.SortOrder = localDataBlocks[0]->SortOrder; + // FIXME: Commented out to avoid compile error, full fix to follow in subsequent merge request + // contourTreeMeshOut.SortOrder = localDataBlocks[0]->SortOrder; contourTreeMeshOut.SortedValues = localDataBlocks[0]->SortedValue; contourTreeMeshOut.GlobalMeshIndex = localDataBlocks[0]->GlobalMeshIndex; contourTreeMeshOut.Neighbours = localDataBlocks[0]->Neighbours; @@ -390,10 +388,7 @@ VTKM_CONT void ContourTreeUniformDistributed::DoPostExecute( maxIdx[1] = maxIdx[1] - 1; maxIdx[2] = maxIdx[2] > 0 ? (maxIdx[2] - 1) : 0; auto meshBoundaryExecObj = contourTreeMeshOut.GetMeshBoundaryExecutionObject( - this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize[0], - this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize[1], - minIdx, - maxIdx); + this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize, minIdx, maxIdx); // Run the worklet to compute the final contour tree worklet.Run( contourTreeMeshOut.SortedValues, // Unused param. Provide something to keep API happy From 1074c0172bc92561b6bce447d01bfaff6848ec70 Mon Sep 17 00:00:00 2001 From: "Gunther H. Weber" Date: Fri, 18 Sep 2020 06:33:09 -0700 Subject: [PATCH 42/51] Commented out incomplete code creating a warning --- .../contour_tree_augmented/ContourTreeApp.cxx | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/examples/contour_tree_augmented/ContourTreeApp.cxx b/examples/contour_tree_augmented/ContourTreeApp.cxx index 5b947e8e8..9a607d5f9 100644 --- a/examples/contour_tree_augmented/ContourTreeApp.cxx +++ b/examples/contour_tree_augmented/ContourTreeApp.cxx @@ -448,17 +448,21 @@ int main(int argc, char* argv[]) dims[0] = meshSize[0]; dims[1] = meshSize[1]; dims[2] = meshSize[2]; - auto tempField = inDataSet.GetField("values").GetData(); - values.resize(static_cast(tempField.GetNumberOfValues())); - auto tempFieldHandle = tempField.AsVirtual().ReadPortal(); - for (vtkm::Id i = 0; i < tempField.GetNumberOfValues(); i++) - { - values[static_cast(i)] = static_cast(tempFieldHandle.Get(i)); - } + // TODO/FIXME: The following is commented out since it creates a a warning that + // AsVirtual() will no longer be supported. Since this implementation is + // incomplete anyway, it currently makes more sense to comment it out than + // to fix the warning. + // auto tempField = inDataSet.GetField("values").GetData(); + // values.resize(static_cast(tempField.GetNumberOfValues())); + // auto tempFieldHandle = tempField.AsVirtual().ReadPortal(); + // for (vtkm::Id i = 0; i < tempField.GetNumberOfValues(); i++) + // { + // values[static_cast(i)] = static_cast(tempFieldHandle.Get(i)); + // } VTKM_LOG_S(vtkm::cont::LogLevel::Error, "BOV reader not yet support in MPI mode by this example"); MPI_Finalize(); - return EXIT_SUCCESS; + return EXIT_FAILURE; #endif } else // Read ASCII data input From c9b763aca9649b2805d866b3eb9e626c07d06712 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 21 Sep 2020 14:49:03 -0600 Subject: [PATCH 43/51] Rename PointLocatorUniformGrid to PointLocatorSparseGrid The new name reflects better what the underlying algorithm does. It also helps prevent confusion about what types of data the locator is good for. The old name suggested it only worked for structured grids, which is not the case. --- vtkm/cont/CMakeLists.txt | 3 +- ...ormGrid.cxx => PointLocatorSparseGrid.cxx} | 16 +-- vtkm/cont/PointLocatorSparseGrid.h | 102 ++++++++++++++++++ vtkm/cont/PointLocatorUniformGrid.h | 70 ++---------- vtkm/cont/cuda/testing/CMakeLists.txt | 2 +- ... => UnitTestCudaPointLocatorSparseGrid.cu} | 6 +- vtkm/cont/kokkos/testing/CMakeLists.txt | 2 +- ... UnitTestKokkosPointLocatorSparseGrid.cxx} | 6 +- vtkm/cont/openmp/testing/CMakeLists.txt | 2 +- ... UnitTestOpenMPPointLocatorSparseGrid.cxx} | 6 +- vtkm/cont/serial/testing/CMakeLists.txt | 2 +- ... UnitTestSerialPointLocatorSparseGrid.cxx} | 6 +- vtkm/cont/tbb/testing/CMakeLists.txt | 2 +- ... => UnitTestTBBPointLocatorSparseGrid.cxx} | 6 +- vtkm/cont/testing/CMakeLists.txt | 2 +- ...Grid.h => TestingPointLocatorSparseGrid.h} | 23 ++-- vtkm/exec/CMakeLists.txt | 2 +- ...UniformGrid.h => PointLocatorSparseGrid.h} | 25 ++--- 18 files changed, 164 insertions(+), 119 deletions(-) rename vtkm/cont/{PointLocatorUniformGrid.cxx => PointLocatorSparseGrid.cxx} (90%) create mode 100644 vtkm/cont/PointLocatorSparseGrid.h rename vtkm/cont/cuda/testing/{UnitTestCudaPointLocatorUniformGrid.cu => UnitTestCudaPointLocatorSparseGrid.cu} (74%) rename vtkm/cont/kokkos/testing/{UnitTestKokkosPointLocatorUniformGrid.cxx => UnitTestKokkosPointLocatorSparseGrid.cxx} (74%) rename vtkm/cont/openmp/testing/{UnitTestOpenMPPointLocatorUniformGrid.cxx => UnitTestOpenMPPointLocatorSparseGrid.cxx} (75%) rename vtkm/cont/serial/testing/{UnitTestSerialPointLocatorUniformGrid.cxx => UnitTestSerialPointLocatorSparseGrid.cxx} (74%) rename vtkm/cont/tbb/testing/{UnitTestTBBPointLocatorUniformGrid.cxx => UnitTestTBBPointLocatorSparseGrid.cxx} (74%) rename vtkm/cont/testing/{TestingPointLocatorUniformGrid.h => TestingPointLocatorSparseGrid.h} (90%) rename vtkm/exec/{PointLocatorUniformGrid.h => PointLocatorSparseGrid.h} (92%) diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index 5aef733fc..e492edd5d 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -102,6 +102,7 @@ set(headers PartitionedDataSet.h PointLocator.h PointLocatorUniformGrid.h + PointLocatorSparseGrid.h RuntimeDeviceInformation.h RuntimeDeviceTracker.h Serialization.h @@ -182,7 +183,7 @@ set(sources FieldRangeGlobalCompute.cxx PartitionedDataSet.cxx PointLocator.cxx - PointLocatorUniformGrid.cxx + PointLocatorSparseGrid.cxx RuntimeDeviceInformation.cxx Timer.cxx UnknownArrayHandle.cxx diff --git a/vtkm/cont/PointLocatorUniformGrid.cxx b/vtkm/cont/PointLocatorSparseGrid.cxx similarity index 90% rename from vtkm/cont/PointLocatorUniformGrid.cxx rename to vtkm/cont/PointLocatorSparseGrid.cxx index f3273256a..9ab9c885c 100644 --- a/vtkm/cont/PointLocatorUniformGrid.cxx +++ b/vtkm/cont/PointLocatorSparseGrid.cxx @@ -17,7 +17,7 @@ // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ -#include +#include namespace vtkm { @@ -59,7 +59,7 @@ private: } // internal -void PointLocatorUniformGrid::Build() +void PointLocatorSparseGrid::Build() { if (this->IsRangeInvalid()) { @@ -96,11 +96,11 @@ void PointLocatorUniformGrid::Build() vtkm::cont::Algorithm::LowerBounds(cellIds, cell_ids_counting, this->CellLower); } -struct PointLocatorUniformGrid::PrepareExecutionObjectFunctor +struct PointLocatorSparseGrid::PrepareExecutionObjectFunctor { template VTKM_CONT bool operator()(DeviceAdapter, - const vtkm::cont::PointLocatorUniformGrid& self, + const vtkm::cont::PointLocatorSparseGrid& self, ExecutionObjectHandleType& handle, vtkm::cont::Token& token) const { @@ -110,8 +110,8 @@ struct PointLocatorUniformGrid::PrepareExecutionObjectFunctor auto rmax = vtkm::make_Vec(static_cast(self.Range[0].Max), static_cast(self.Range[1].Max), static_cast(self.Range[2].Max)); - vtkm::exec::PointLocatorUniformGrid* h = - new vtkm::exec::PointLocatorUniformGrid( + vtkm::exec::PointLocatorSparseGrid* h = + new vtkm::exec::PointLocatorSparseGrid( rmin, rmax, self.Dims, @@ -124,7 +124,7 @@ struct PointLocatorUniformGrid::PrepareExecutionObjectFunctor } }; -VTKM_CONT void PointLocatorUniformGrid::PrepareExecutionObject( +VTKM_CONT void PointLocatorSparseGrid::PrepareExecutionObject( ExecutionObjectHandleType& execObjHandle, vtkm::cont::DeviceAdapterId deviceId, vtkm::cont::Token& token) const @@ -133,7 +133,7 @@ VTKM_CONT void PointLocatorUniformGrid::PrepareExecutionObject( deviceId, PrepareExecutionObjectFunctor(), *this, execObjHandle, token); if (!success) { - throwFailedRuntimeDeviceTransfer("PointLocatorUniformGrid", deviceId); + throwFailedRuntimeDeviceTransfer("PointLocatorSparseGrid", deviceId); } } } diff --git a/vtkm/cont/PointLocatorSparseGrid.h b/vtkm/cont/PointLocatorSparseGrid.h new file mode 100644 index 000000000..b2b20f28b --- /dev/null +++ b/vtkm/cont/PointLocatorSparseGrid.h @@ -0,0 +1,102 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#ifndef vtk_m_cont_PointLocatorSparseGrid_h +#define vtk_m_cont_PointLocatorSparseGrid_h + +#include +#include +#include +#include +#include + +#include +#include + +namespace vtkm +{ +namespace cont +{ + +/// \brief A locator that bins points in a sparsely stored grid. +/// +/// `PointLocatorSparseGrid` creates a very dense logical grid over the region containing +/// the points of the provided data set. Although this logical grid has uniform structure, +/// it is stored sparsely. So, it is expected that most of the bins in the structure will +/// be empty but not explicitly stored. This makes `PointLocatorSparseGrid` a good +/// representation for unstructured or irregular collections of points. +/// +/// The algorithm used in `PointLocatorSparseGrid` is described in the following publication: +/// +/// Abhishek Yenpure, Hank Childs, and Kenneth Moreland. "Efficient Point Merging Using Data +/// Parallel Techniques." In _Eurographics Symposium on Parallel Graphics and Visualization +/// (EGPGV)_, June 2019. DOI 10.2312/pgv.20191112. +/// +class VTKM_CONT_EXPORT PointLocatorSparseGrid : public vtkm::cont::PointLocator +{ +public: + using RangeType = vtkm::Vec; + + void SetRange(const RangeType& range) + { + if (this->Range != range) + { + this->Range = range; + this->SetModified(); + } + } + + const RangeType& GetRange() const { return this->Range; } + + void SetComputeRangeFromCoordinates() + { + if (!this->IsRangeInvalid()) + { + this->Range = { { 0.0, -1.0 } }; + this->SetModified(); + } + } + + void SetNumberOfBins(const vtkm::Id3& bins) + { + if (this->Dims != bins) + { + this->Dims = bins; + this->SetModified(); + } + } + + const vtkm::Id3& GetNumberOfBins() const { return this->Dims; } + +protected: + void Build() override; + + struct PrepareExecutionObjectFunctor; + + VTKM_CONT void PrepareExecutionObject(ExecutionObjectHandleType& execObjHandle, + vtkm::cont::DeviceAdapterId deviceId, + vtkm::cont::Token& token) const override; + + bool IsRangeInvalid() const + { + return (this->Range[0].Max < this->Range[0].Min) || (this->Range[1].Max < this->Range[1].Min) || + (this->Range[2].Max < this->Range[2].Min); + } + +private: + RangeType Range = { { 0.0, -1.0 } }; + vtkm::Id3 Dims = { 32 }; + + vtkm::cont::ArrayHandle PointIds; + vtkm::cont::ArrayHandle CellLower; + vtkm::cont::ArrayHandle CellUpper; +}; +} +} +#endif //vtk_m_cont_PointLocatorSparseGrid_h diff --git a/vtkm/cont/PointLocatorUniformGrid.h b/vtkm/cont/PointLocatorUniformGrid.h index d8cc04cbc..4e8fe8dcf 100644 --- a/vtkm/cont/PointLocatorUniformGrid.h +++ b/vtkm/cont/PointLocatorUniformGrid.h @@ -10,79 +10,21 @@ #ifndef vtk_m_cont_PointLocatorUniformGrid_h #define vtk_m_cont_PointLocatorUniformGrid_h -#include -#include -#include -#include -#include +#include -#include -#include +#include namespace vtkm { namespace cont { -class VTKM_CONT_EXPORT PointLocatorUniformGrid : public vtkm::cont::PointLocator +struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Replaced with PointLocatorSparseGrid.") + PointLocatorUniformGrid : vtkm::cont::PointLocatorSparseGrid { -public: - using RangeType = vtkm::Vec; - - void SetRange(const RangeType& range) - { - if (this->Range != range) - { - this->Range = range; - this->SetModified(); - } - } - - const RangeType& GetRange() const { return this->Range; } - - void SetComputeRangeFromCoordinates() - { - if (!this->IsRangeInvalid()) - { - this->Range = { { 0.0, -1.0 } }; - this->SetModified(); - } - } - - void SetNumberOfBins(const vtkm::Id3& bins) - { - if (this->Dims != bins) - { - this->Dims = bins; - this->SetModified(); - } - } - - const vtkm::Id3& GetNumberOfBins() const { return this->Dims; } - -protected: - void Build() override; - - struct PrepareExecutionObjectFunctor; - - VTKM_CONT void PrepareExecutionObject(ExecutionObjectHandleType& execObjHandle, - vtkm::cont::DeviceAdapterId deviceId, - vtkm::cont::Token& token) const override; - - bool IsRangeInvalid() const - { - return (this->Range[0].Max < this->Range[0].Min) || (this->Range[1].Max < this->Range[1].Min) || - (this->Range[2].Max < this->Range[2].Min); - } - -private: - RangeType Range = { { 0.0, -1.0 } }; - vtkm::Id3 Dims = { 32 }; - - vtkm::cont::ArrayHandle PointIds; - vtkm::cont::ArrayHandle CellLower; - vtkm::cont::ArrayHandle CellUpper; }; + } } + #endif //vtk_m_cont_PointLocatorUniformGrid_h diff --git a/vtkm/cont/cuda/testing/CMakeLists.txt b/vtkm/cont/cuda/testing/CMakeLists.txt index b23f65c5a..398abacf5 100644 --- a/vtkm/cont/cuda/testing/CMakeLists.txt +++ b/vtkm/cont/cuda/testing/CMakeLists.txt @@ -25,7 +25,7 @@ set(unit_tests UnitTestCudaIterators.cu UnitTestCudaMathEdgeCases.cu UnitTestCudaShareUserProvidedManagedMemory.cu - UnitTestCudaPointLocatorUniformGrid.cu + UnitTestCudaPointLocatorSparseGrid.cu UnitTestCudaVirtualObjectHandle.cu ) vtkm_unit_tests(SOURCES ${unit_tests} LABEL "CUDA" LIBRARIES vtkm_worklet) diff --git a/vtkm/cont/cuda/testing/UnitTestCudaPointLocatorUniformGrid.cu b/vtkm/cont/cuda/testing/UnitTestCudaPointLocatorSparseGrid.cu similarity index 74% rename from vtkm/cont/cuda/testing/UnitTestCudaPointLocatorUniformGrid.cu rename to vtkm/cont/cuda/testing/UnitTestCudaPointLocatorSparseGrid.cu index 01d929413..d1bbc1192 100644 --- a/vtkm/cont/cuda/testing/UnitTestCudaPointLocatorUniformGrid.cu +++ b/vtkm/cont/cuda/testing/UnitTestCudaPointLocatorSparseGrid.cu @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include -int UnitTestCudaPointLocatorUniformGrid(int argc, char* argv[]) +int UnitTestCudaPointLocatorSparseGrid(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{}); return vtkm::cont::testing::Testing::Run( - TestingPointLocatorUniformGrid(), argc, argv); + TestingPointLocatorSparseGrid(), argc, argv); } diff --git a/vtkm/cont/kokkos/testing/CMakeLists.txt b/vtkm/cont/kokkos/testing/CMakeLists.txt index a40f93048..e6907f4f7 100644 --- a/vtkm/cont/kokkos/testing/CMakeLists.txt +++ b/vtkm/cont/kokkos/testing/CMakeLists.txt @@ -22,7 +22,7 @@ set(unit_tests UnitTestKokkosDataSetSingleType.cxx UnitTestKokkosDeviceAdapter.cxx UnitTestKokkosImplicitFunction.cxx - UnitTestKokkosPointLocatorUniformGrid.cxx + UnitTestKokkosPointLocatorSparseGrid.cxx UnitTestKokkosVirtualObjectHandle.cxx ) vtkm_unit_tests(SOURCES ${unit_tests} LABEL "KOKKOS" LIBRARIES vtkm_worklet) diff --git a/vtkm/cont/kokkos/testing/UnitTestKokkosPointLocatorUniformGrid.cxx b/vtkm/cont/kokkos/testing/UnitTestKokkosPointLocatorSparseGrid.cxx similarity index 74% rename from vtkm/cont/kokkos/testing/UnitTestKokkosPointLocatorUniformGrid.cxx rename to vtkm/cont/kokkos/testing/UnitTestKokkosPointLocatorSparseGrid.cxx index d6d113b53..c0c716964 100644 --- a/vtkm/cont/kokkos/testing/UnitTestKokkosPointLocatorUniformGrid.cxx +++ b/vtkm/cont/kokkos/testing/UnitTestKokkosPointLocatorSparseGrid.cxx @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include -int UnitTestKokkosPointLocatorUniformGrid(int argc, char* argv[]) +int UnitTestKokkosPointLocatorSparseGrid(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagKokkos{}); return vtkm::cont::testing::Testing::Run( - TestingPointLocatorUniformGrid(), argc, argv); + TestingPointLocatorSparseGrid(), argc, argv); } diff --git a/vtkm/cont/openmp/testing/CMakeLists.txt b/vtkm/cont/openmp/testing/CMakeLists.txt index 2f3c4af2f..5dfea2669 100644 --- a/vtkm/cont/openmp/testing/CMakeLists.txt +++ b/vtkm/cont/openmp/testing/CMakeLists.txt @@ -22,7 +22,7 @@ set(unit_tests UnitTestOpenMPDataSetSingleType.cxx UnitTestOpenMPDeviceAdapter.cxx UnitTestOpenMPImplicitFunction.cxx - UnitTestOpenMPPointLocatorUniformGrid.cxx + UnitTestOpenMPPointLocatorSparseGrid.cxx UnitTestOpenMPVirtualObjectHandle.cxx ) vtkm_unit_tests(SOURCES ${unit_tests} diff --git a/vtkm/cont/openmp/testing/UnitTestOpenMPPointLocatorUniformGrid.cxx b/vtkm/cont/openmp/testing/UnitTestOpenMPPointLocatorSparseGrid.cxx similarity index 75% rename from vtkm/cont/openmp/testing/UnitTestOpenMPPointLocatorUniformGrid.cxx rename to vtkm/cont/openmp/testing/UnitTestOpenMPPointLocatorSparseGrid.cxx index 1fcd44767..79a4e009d 100644 --- a/vtkm/cont/openmp/testing/UnitTestOpenMPPointLocatorUniformGrid.cxx +++ b/vtkm/cont/openmp/testing/UnitTestOpenMPPointLocatorSparseGrid.cxx @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ #include -#include +#include -int UnitTestOpenMPPointLocatorUniformGrid(int argc, char* argv[]) +int UnitTestOpenMPPointLocatorSparseGrid(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{}); return vtkm::cont::testing::Testing::Run( - TestingPointLocatorUniformGrid(), argc, argv); + TestingPointLocatorSparseGrid(), argc, argv); } diff --git a/vtkm/cont/serial/testing/CMakeLists.txt b/vtkm/cont/serial/testing/CMakeLists.txt index 787a2631b..433a34a49 100644 --- a/vtkm/cont/serial/testing/CMakeLists.txt +++ b/vtkm/cont/serial/testing/CMakeLists.txt @@ -22,7 +22,7 @@ set(unit_tests UnitTestSerialDataSetSingleType.cxx UnitTestSerialDeviceAdapter.cxx UnitTestSerialImplicitFunction.cxx - UnitTestSerialPointLocatorUniformGrid.cxx + UnitTestSerialPointLocatorSparseGrid.cxx UnitTestSerialVirtualObjectHandle.cxx ) vtkm_unit_tests(SOURCES ${unit_tests} diff --git a/vtkm/cont/serial/testing/UnitTestSerialPointLocatorUniformGrid.cxx b/vtkm/cont/serial/testing/UnitTestSerialPointLocatorSparseGrid.cxx similarity index 74% rename from vtkm/cont/serial/testing/UnitTestSerialPointLocatorUniformGrid.cxx rename to vtkm/cont/serial/testing/UnitTestSerialPointLocatorSparseGrid.cxx index 31db1e2e1..242c094f1 100644 --- a/vtkm/cont/serial/testing/UnitTestSerialPointLocatorUniformGrid.cxx +++ b/vtkm/cont/serial/testing/UnitTestSerialPointLocatorSparseGrid.cxx @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include -int UnitTestSerialPointLocatorUniformGrid(int argc, char* argv[]) +int UnitTestSerialPointLocatorSparseGrid(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagSerial{}); return vtkm::cont::testing::Testing::Run( - TestingPointLocatorUniformGrid(), argc, argv); + TestingPointLocatorSparseGrid(), argc, argv); } diff --git a/vtkm/cont/tbb/testing/CMakeLists.txt b/vtkm/cont/tbb/testing/CMakeLists.txt index ed484b9b9..e6c3726f7 100644 --- a/vtkm/cont/tbb/testing/CMakeLists.txt +++ b/vtkm/cont/tbb/testing/CMakeLists.txt @@ -22,7 +22,7 @@ set(unit_tests UnitTestTBBDataSetSingleType.cxx UnitTestTBBDeviceAdapter.cxx UnitTestTBBImplicitFunction.cxx - UnitTestTBBPointLocatorUniformGrid.cxx + UnitTestTBBPointLocatorSparseGrid.cxx UnitTestTBBVirtualObjectHandle.cxx ) diff --git a/vtkm/cont/tbb/testing/UnitTestTBBPointLocatorUniformGrid.cxx b/vtkm/cont/tbb/testing/UnitTestTBBPointLocatorSparseGrid.cxx similarity index 74% rename from vtkm/cont/tbb/testing/UnitTestTBBPointLocatorUniformGrid.cxx rename to vtkm/cont/tbb/testing/UnitTestTBBPointLocatorSparseGrid.cxx index 05f03aec4..159e7aaf2 100644 --- a/vtkm/cont/tbb/testing/UnitTestTBBPointLocatorUniformGrid.cxx +++ b/vtkm/cont/tbb/testing/UnitTestTBBPointLocatorSparseGrid.cxx @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include -int UnitTestTBBPointLocatorUniformGrid(int argc, char* argv[]) +int UnitTestTBBPointLocatorSparseGrid(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{}); return vtkm::cont::testing::Testing::Run( - TestingPointLocatorUniformGrid(), argc, argv); + TestingPointLocatorSparseGrid(), argc, argv); } diff --git a/vtkm/cont/testing/CMakeLists.txt b/vtkm/cont/testing/CMakeLists.txt index 38ec5ac03..fbb04c7dd 100644 --- a/vtkm/cont/testing/CMakeLists.txt +++ b/vtkm/cont/testing/CMakeLists.txt @@ -24,7 +24,7 @@ set(headers TestingDataSetSingleType.h TestingFancyArrayHandles.h TestingImplicitFunction.h - TestingPointLocatorUniformGrid.h + TestingPointLocatorSparseGrid.h TestingSerialization.h TestingVirtualObjectHandle.h ) diff --git a/vtkm/cont/testing/TestingPointLocatorUniformGrid.h b/vtkm/cont/testing/TestingPointLocatorSparseGrid.h similarity index 90% rename from vtkm/cont/testing/TestingPointLocatorUniformGrid.h rename to vtkm/cont/testing/TestingPointLocatorSparseGrid.h index 8aaf674c9..981bdeafa 100644 --- a/vtkm/cont/testing/TestingPointLocatorUniformGrid.h +++ b/vtkm/cont/testing/TestingPointLocatorSparseGrid.h @@ -8,15 +8,14 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_cont_testing_TestingPointLocatorUniformGrid_h -#define vtk_m_cont_testing_TestingPointLocatorUniformGrid_h +#ifndef vtk_m_cont_testing_TestingPointLocatorSparseGrid_h +#define vtk_m_cont_testing_TestingPointLocatorSparseGrid_h #include #include -#include -#include +#include ////brute force method ///// template @@ -65,7 +64,7 @@ public: } }; -class PointLocatorUniformGridWorklet : public vtkm::worklet::WorkletMapField +class PointLocatorSparseGridWorklet : public vtkm::worklet::WorkletMapField { public: typedef void ControlSignature(FieldIn qcIn, @@ -76,7 +75,7 @@ public: typedef void ExecutionSignature(_1, _2, _3, _4); VTKM_CONT - PointLocatorUniformGridWorklet() {} + PointLocatorSparseGridWorklet() {} template VTKM_EXEC void operator()(const CoordiVecType& qc, @@ -89,7 +88,7 @@ public: }; template -class TestingPointLocatorUniformGrid +class TestingPointLocatorSparseGrid { public: using Algorithm = vtkm::cont::DeviceAdapterAlgorithm; @@ -122,7 +121,7 @@ public: vtkm::cont::CoordinateSystem coord("points", coordi_Handle); - vtkm::cont::PointLocatorUniformGrid pointLocatorUG; + vtkm::cont::PointLocatorSparseGrid pointLocatorUG; pointLocatorUG.SetCoordinates(coord); pointLocatorUG.SetRange({ { 0.0, 10.0 } }); pointLocatorUG.SetNumberOfBins({ 5, 5, 5 }); @@ -150,9 +149,9 @@ public: vtkm::cont::ArrayHandle nnId_Handle; vtkm::cont::ArrayHandle nnDis_Handle; - PointLocatorUniformGridWorklet pointLocatorUniformGridWorklet; - vtkm::worklet::DispatcherMapField locatorDispatcher( - pointLocatorUniformGridWorklet); + PointLocatorSparseGridWorklet pointLocatorSparseGridWorklet; + vtkm::worklet::DispatcherMapField locatorDispatcher( + pointLocatorSparseGridWorklet); locatorDispatcher.SetDevice(DeviceAdapter()); locatorDispatcher.Invoke(qc_Handle, locator, nnId_Handle, nnDis_Handle); @@ -193,4 +192,4 @@ public: } }; -#endif // vtk_m_cont_testing_TestingPointLocatorUniformGrid_h +#endif // vtk_m_cont_testing_TestingPointLocatorSparseGrid_h diff --git a/vtkm/exec/CMakeLists.txt b/vtkm/exec/CMakeLists.txt index 1cf389f63..93f74fe86 100644 --- a/vtkm/exec/CMakeLists.txt +++ b/vtkm/exec/CMakeLists.txt @@ -31,7 +31,7 @@ set(headers FunctorBase.h ParametricCoordinates.h PointLocator.h - PointLocatorUniformGrid.h + PointLocatorSparseGrid.h TaskBase.h ) diff --git a/vtkm/exec/PointLocatorUniformGrid.h b/vtkm/exec/PointLocatorSparseGrid.h similarity index 92% rename from vtkm/exec/PointLocatorUniformGrid.h rename to vtkm/exec/PointLocatorSparseGrid.h index 1984a4aae..9d1b40701 100644 --- a/vtkm/exec/PointLocatorUniformGrid.h +++ b/vtkm/exec/PointLocatorSparseGrid.h @@ -7,8 +7,8 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_exec_PointLocatorUniformGrid_h -#define vtk_m_exec_PointLocatorUniformGrid_h +#ifndef vtk_m_exec_PointLocatorSparseGrid_h +#define vtk_m_exec_PointLocatorSparseGrid_h #include #include @@ -18,6 +18,7 @@ #include +#include #include namespace vtkm @@ -26,7 +27,7 @@ namespace exec { template -class VTKM_ALWAYS_EXPORT PointLocatorUniformGrid final : public vtkm::exec::PointLocator +class VTKM_ALWAYS_EXPORT PointLocatorSparseGrid : public vtkm::exec::PointLocator { public: using CoordPortalType = @@ -36,15 +37,15 @@ public: typename vtkm::cont::ArrayHandle::template ExecutionTypes::PortalConst; - PointLocatorUniformGrid() = default; + PointLocatorSparseGrid() = default; - PointLocatorUniformGrid(const vtkm::Vec3f& min, - const vtkm::Vec3f& max, - const vtkm::Id3& dims, - const CoordPortalType& coords, - const IdPortalType& pointIds, - const IdPortalType& cellLower, - const IdPortalType& cellUpper) + PointLocatorSparseGrid(const vtkm::Vec3f& min, + const vtkm::Vec3f& max, + const vtkm::Id3& dims, + const CoordPortalType& coords, + const IdPortalType& pointIds, + const IdPortalType& cellLower, + const IdPortalType& cellUpper) : Min(min) , Dims(dims) , Dxdydz((max - Min) / Dims) @@ -237,4 +238,4 @@ private: } } -#endif // vtk_m_exec_PointLocatorUniformGrid_h +#endif // vtk_m_exec_PointLocatorSparseGrid_h From b012c42bebd24a92f9cbc86ca65c3df4029b32ad Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Mon, 21 Sep 2020 15:35:30 -0600 Subject: [PATCH 44/51] Rename CellLocatorUniformBins to CellLocatorTwoLevel The new name is more descriptive and prevents confusion with CellLocatorUniformGrid. --- CTestCustom.cmake.in | 2 +- vtkm/cont/CMakeLists.txt | 3 +- vtkm/cont/CellLocatorGeneral.cxx | 6 +- ...niformBins.cxx => CellLocatorTwoLevel.cxx} | 36 +-- vtkm/cont/CellLocatorTwoLevel.h | 93 ++++++ vtkm/cont/CellLocatorUniformBins.h | 278 +----------------- vtkm/cont/cuda/testing/CMakeLists.txt | 2 +- ....cu => UnitTestCudaCellLocatorTwoLevel.cu} | 6 +- vtkm/cont/kokkos/testing/CMakeLists.txt | 2 +- ... => UnitTestKokkosCellLocatorTwoLevel.cxx} | 6 +- vtkm/cont/openmp/testing/CMakeLists.txt | 2 +- ... => UnitTestOpenMPCellLocatorTwoLevel.cxx} | 6 +- vtkm/cont/serial/testing/CMakeLists.txt | 2 +- ... => UnitTestSerialCellLocatorTwoLevel.cxx} | 6 +- vtkm/cont/tbb/testing/CMakeLists.txt | 2 +- ...cxx => UnitTestTBBCellLocatorTwoLevel.cxx} | 6 +- vtkm/cont/testing/CMakeLists.txt | 2 +- ...ormBins.h => TestingCellLocatorTwoLevel.h} | 12 +- vtkm/exec/CMakeLists.txt | 1 + vtkm/exec/CellLocatorTwoLevel.h | 229 +++++++++++++++ .../particleadvection/GridEvaluatorStatus.h | 2 +- .../particleadvection/GridEvaluators.h | 14 +- 22 files changed, 390 insertions(+), 328 deletions(-) rename vtkm/cont/{CellLocatorUniformBins.cxx => CellLocatorTwoLevel.cxx} (95%) create mode 100644 vtkm/cont/CellLocatorTwoLevel.h rename vtkm/cont/cuda/testing/{UnitTestCudaCellLocatorUniformBins.cu => UnitTestCudaCellLocatorTwoLevel.cu} (75%) rename vtkm/cont/kokkos/testing/{UnitTestKokkosCellLocatorUniformBins.cxx => UnitTestKokkosCellLocatorTwoLevel.cxx} (74%) rename vtkm/cont/openmp/testing/{UnitTestOpenMPCellLocatorUniformBins.cxx => UnitTestOpenMPCellLocatorTwoLevel.cxx} (76%) rename vtkm/cont/serial/testing/{UnitTestSerialCellLocatorUniformBins.cxx => UnitTestSerialCellLocatorTwoLevel.cxx} (76%) rename vtkm/cont/tbb/testing/{UnitTestTBBCellLocatorUniformBins.cxx => UnitTestTBBCellLocatorTwoLevel.cxx} (75%) rename vtkm/cont/testing/{TestingCellLocatorUniformBins.h => TestingCellLocatorTwoLevel.h} (96%) create mode 100644 vtkm/exec/CellLocatorTwoLevel.h diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index ce0bfb1bf..fd44cc3cd 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -55,7 +55,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION "nvlink warning : .*ArrayPortalVirtual.* has address taken but no possible call to it" "nvlink warning : .*CellLocatorBoundingIntervalHierarchyExec.* has address taken but no possible call to it" "nvlink warning : .*CellLocatorRectilinearGrid.* has address taken but no possible call to it" - "nvlink warning : .*CellLocatorUniformBins.* has address taken but no possible call to it" + "nvlink warning : .*CellLocatorTwoLevel.* has address taken but no possible call to it" "nvlink warning : .*CellLocatorUniformGrid.* has address taken but no possible call to it" ) diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index e492edd5d..2d6002e1d 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -55,6 +55,7 @@ set(headers CellLocatorBoundingIntervalHierarchy.h CellLocatorGeneral.h CellLocatorRectilinearGrid.h + CellLocatorTwoLevel.h CellLocatorUniformBins.h CellLocatorUniformGrid.h CellSet.h @@ -166,7 +167,7 @@ set(sources CellLocatorBoundingIntervalHierarchy.cxx CellLocatorGeneral.cxx CellLocatorRectilinearGrid.cxx - CellLocatorUniformBins.cxx + CellLocatorTwoLevel.cxx CellLocatorUniformGrid.cxx CellSet.cxx CellSetExplicit.cxx diff --git a/vtkm/cont/CellLocatorGeneral.cxx b/vtkm/cont/CellLocatorGeneral.cxx index 22d7de220..475aeda9b 100644 --- a/vtkm/cont/CellLocatorGeneral.cxx +++ b/vtkm/cont/CellLocatorGeneral.cxx @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include @@ -46,9 +46,9 @@ void DefaultConfigurator(std::unique_ptr& locator, locator.reset(new vtkm::cont::CellLocatorRectilinearGrid); } } - else if (!dynamic_cast(locator.get())) + else if (!dynamic_cast(locator.get())) { - locator.reset(new vtkm::cont::CellLocatorUniformBins); + locator.reset(new vtkm::cont::CellLocatorTwoLevel); } locator->SetCellSet(cellSet); diff --git a/vtkm/cont/CellLocatorUniformBins.cxx b/vtkm/cont/CellLocatorTwoLevel.cxx similarity index 95% rename from vtkm/cont/CellLocatorUniformBins.cxx rename to vtkm/cont/CellLocatorTwoLevel.cxx index 0caccbb03..89502dd85 100644 --- a/vtkm/cont/CellLocatorUniformBins.cxx +++ b/vtkm/cont/CellLocatorTwoLevel.cxx @@ -7,7 +7,7 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include @@ -345,7 +345,7 @@ namespace cont //---------------------------------------------------------------------------- /// Builds the cell locator lookup structure /// -VTKM_CONT void CellLocatorUniformBins::Build() +VTKM_CONT void CellLocatorTwoLevel::Build() { vtkm::cont::Invoker invoke; @@ -453,53 +453,53 @@ VTKM_CONT void CellLocatorUniformBins::Build() } //---------------------------------------------------------------------------- -struct CellLocatorUniformBins::MakeExecObject +struct CellLocatorTwoLevel::MakeExecObject { template VTKM_CONT void operator()(const CellSetType& cellSet, DeviceAdapter, vtkm::cont::Token& token, - const CellLocatorUniformBins& self) const + const CellLocatorTwoLevel& self) const { auto execObject = - new vtkm::exec::CellLocatorUniformBins(self.TopLevel, - self.LeafDimensions, - self.LeafStartIndex, - self.CellStartIndex, - self.CellCount, - self.CellIds, - cellSet, - self.GetCoordinates(), - token); + new vtkm::exec::CellLocatorTwoLevel(self.TopLevel, + self.LeafDimensions, + self.LeafStartIndex, + self.CellStartIndex, + self.CellCount, + self.CellIds, + cellSet, + self.GetCoordinates(), + token); self.ExecutionObjectHandle.Reset(execObject); } }; -struct CellLocatorUniformBins::PrepareForExecutionFunctor +struct CellLocatorTwoLevel::PrepareForExecutionFunctor { template VTKM_CONT bool operator()(DeviceAdapter, vtkm::cont::Token& token, - const CellLocatorUniformBins& self) const + const CellLocatorTwoLevel& self) const { self.GetCellSet().CastAndCall(MakeExecObject{}, DeviceAdapter{}, token, self); return true; } }; -VTKM_CONT const vtkm::exec::CellLocator* CellLocatorUniformBins::PrepareForExecution( +VTKM_CONT const vtkm::exec::CellLocator* CellLocatorTwoLevel::PrepareForExecution( vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const { if (!vtkm::cont::TryExecuteOnDevice(device, PrepareForExecutionFunctor(), token, *this)) { - throwFailedRuntimeDeviceTransfer("CellLocatorUniformBins", device); + throwFailedRuntimeDeviceTransfer("CellLocatorTwoLevel", device); } return this->ExecutionObjectHandle.PrepareForExecution(device, token); } //---------------------------------------------------------------------------- -void CellLocatorUniformBins::PrintSummary(std::ostream& out) const +void CellLocatorTwoLevel::PrintSummary(std::ostream& out) const { out << "DensityL1: " << this->DensityL1 << "\n"; out << "DensityL2: " << this->DensityL2 << "\n"; diff --git a/vtkm/cont/CellLocatorTwoLevel.h b/vtkm/cont/CellLocatorTwoLevel.h new file mode 100644 index 000000000..f051fd23c --- /dev/null +++ b/vtkm/cont/CellLocatorTwoLevel.h @@ -0,0 +1,93 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#ifndef vtk_m_cont_CellLocatorTwoLevel_h +#define vtk_m_cont_CellLocatorTwoLevel_h + +#include +#include +#include + +#include + + +namespace vtkm +{ +namespace cont +{ + +/// \brief A locator that uses 2 nested levels of grids. +/// +/// `CellLocatorTwoLevel` creates a cell search structure using two levels of structured +/// grids. The first level is a coarse grid that covers the entire region of the data. +/// It is expected that the distributions of dataset cells in this coarse grid will be +/// very uneven. Within each bin of the coarse grid, a second level grid is defined within +/// the spatial bounds of the coarse bin. The size of this second level grid is proportional +/// to the number of cells in the first level. In this way, the second level grids adapt +/// to the distribution of cells being located. The adaption is not perfect, but it is +/// has very good space efficiency and is fast to generate and use. +/// +/// The algorithm used in `CellLocatorTwoLevel` is described in the following publication: +/// +/// Javor Kalojanov, Markus Billeter, and Philipp Slusallek. "Two-Level Grids for Ray Tracing +/// on GPUs." _Computer Graphics Forum_, 2011, pages 307-314. DOI 10.1111/j.1467-8659.2011.01862.x +/// +class VTKM_CONT_EXPORT CellLocatorTwoLevel : public vtkm::cont::CellLocator +{ +public: + CellLocatorTwoLevel() + : DensityL1(32.0f) + , DensityL2(2.0f) + { + } + + /// Get/Set the desired approximate number of cells per level 1 bin + /// + void SetDensityL1(vtkm::FloatDefault val) + { + this->DensityL1 = val; + this->SetModified(); + } + vtkm::FloatDefault GetDensityL1() const { return this->DensityL1; } + + /// Get/Set the desired approximate number of cells per level 1 bin + /// + void SetDensityL2(vtkm::FloatDefault val) + { + this->DensityL2 = val; + this->SetModified(); + } + vtkm::FloatDefault GetDensityL2() const { return this->DensityL2; } + + void PrintSummary(std::ostream& out) const; + + const vtkm::exec::CellLocator* PrepareForExecution(vtkm::cont::DeviceAdapterId device, + vtkm::cont::Token& token) const override; + +private: + VTKM_CONT void Build() override; + + vtkm::FloatDefault DensityL1, DensityL2; + + vtkm::internal::cl_uniform_bins::Grid TopLevel; + vtkm::cont::ArrayHandle LeafDimensions; + vtkm::cont::ArrayHandle LeafStartIndex; + vtkm::cont::ArrayHandle CellStartIndex; + vtkm::cont::ArrayHandle CellCount; + vtkm::cont::ArrayHandle CellIds; + + mutable vtkm::cont::VirtualObjectHandle ExecutionObjectHandle; + + struct MakeExecObject; + struct PrepareForExecutionFunctor; +}; +} +} // vtkm::cont + +#endif // vtk_m_cont_CellLocatorTwoLevel_h diff --git a/vtkm/cont/CellLocatorUniformBins.h b/vtkm/cont/CellLocatorUniformBins.h index c5a5d2791..4c3010b5c 100644 --- a/vtkm/cont/CellLocatorUniformBins.h +++ b/vtkm/cont/CellLocatorUniformBins.h @@ -10,283 +10,21 @@ #ifndef vtk_m_cont_CellLocatorUniformBins_h #define vtk_m_cont_CellLocatorUniformBins_h -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -namespace vtkm -{ -namespace internal -{ -namespace cl_uniform_bins -{ - -using DimensionType = vtkm::Int16; -using DimVec3 = vtkm::Vec; -using FloatVec3 = vtkm::Vec3f; - -struct Grid -{ - DimVec3 Dimensions; - FloatVec3 Origin; - FloatVec3 BinSize; -}; - -struct Bounds -{ - FloatVec3 Min; - FloatVec3 Max; -}; - -VTKM_EXEC inline vtkm::Id ComputeFlatIndex(const DimVec3& idx, const DimVec3 dim) -{ - return idx[0] + (dim[0] * (idx[1] + (dim[1] * idx[2]))); -} - -VTKM_EXEC inline Grid ComputeLeafGrid(const DimVec3& idx, const DimVec3& dim, const Grid& l1Grid) -{ - return { dim, - l1Grid.Origin + (static_cast(idx) * l1Grid.BinSize), - l1Grid.BinSize / static_cast(dim) }; -} - -template -VTKM_EXEC inline Bounds ComputeCellBounds(const PointsVecType& points) -{ - using CoordsType = typename vtkm::VecTraits::ComponentType; - auto numPoints = vtkm::VecTraits::GetNumberOfComponents(points); - - CoordsType minp = points[0], maxp = points[0]; - for (vtkm::IdComponent i = 1; i < numPoints; ++i) - { - minp = vtkm::Min(minp, points[i]); - maxp = vtkm::Max(maxp, points[i]); - } - - return { FloatVec3(minp), FloatVec3(maxp) }; -} -} -} -} // vtkm::internal::cl_uniform_bins - -namespace vtkm -{ -namespace exec -{ - -//-------------------------------------------------------------------- -template -class VTKM_ALWAYS_EXPORT CellLocatorUniformBins : public vtkm::exec::CellLocator -{ -private: - using DimVec3 = vtkm::internal::cl_uniform_bins::DimVec3; - using FloatVec3 = vtkm::internal::cl_uniform_bins::FloatVec3; - - template - using ArrayPortalConst = - typename vtkm::cont::ArrayHandle::template ExecutionTypes::PortalConst; - - using CoordsPortalType = - typename vtkm::cont::CoordinateSystem::MultiplexerArrayType::ExecutionTypes< - DeviceAdapter>::PortalConst; - - using CellSetP2CExecType = - decltype(std::declval().PrepareForInput(DeviceAdapter{}, - vtkm::TopologyElementTagCell{}, - vtkm::TopologyElementTagPoint{}, - std::declval())); - - // TODO: This function may return false positives for non 3D cells as the - // tests are done on the projection of the point on the cell. Extra checks - // should be added to test if the point actually falls on the cell. - template - VTKM_EXEC static vtkm::ErrorCode PointInsideCell(FloatVec3 point, - CellShapeTag cellShape, - CoordsType cellPoints, - FloatVec3& parametricCoordinates, - bool& inside) - { - auto bounds = vtkm::internal::cl_uniform_bins::ComputeCellBounds(cellPoints); - if (point[0] >= bounds.Min[0] && point[0] <= bounds.Max[0] && point[1] >= bounds.Min[1] && - point[1] <= bounds.Max[1] && point[2] >= bounds.Min[2] && point[2] <= bounds.Max[2]) - { - VTKM_RETURN_ON_ERROR(vtkm::exec::WorldCoordinatesToParametricCoordinates( - cellPoints, point, cellShape, parametricCoordinates)); - inside = vtkm::exec::CellInside(parametricCoordinates, cellShape); - } - else - { - inside = false; - } - // Return success error code even point is not inside this cell - return vtkm::ErrorCode::Success; - } - -public: - VTKM_CONT CellLocatorUniformBins(const vtkm::internal::cl_uniform_bins::Grid& topLevelGrid, - const vtkm::cont::ArrayHandle& leafDimensions, - const vtkm::cont::ArrayHandle& leafStartIndex, - const vtkm::cont::ArrayHandle& cellStartIndex, - const vtkm::cont::ArrayHandle& cellCount, - const vtkm::cont::ArrayHandle& cellIds, - const CellSetType& cellSet, - const vtkm::cont::CoordinateSystem& coords, - vtkm::cont::Token& token) - : TopLevel(topLevelGrid) - , LeafDimensions(leafDimensions.PrepareForInput(DeviceAdapter{}, token)) - , LeafStartIndex(leafStartIndex.PrepareForInput(DeviceAdapter{}, token)) - , CellStartIndex(cellStartIndex.PrepareForInput(DeviceAdapter{}, token)) - , CellCount(cellCount.PrepareForInput(DeviceAdapter{}, token)) - , CellIds(cellIds.PrepareForInput(DeviceAdapter{}, token)) - , CellSet(cellSet.PrepareForInput(DeviceAdapter{}, - vtkm::TopologyElementTagCell{}, - vtkm::TopologyElementTagPoint{}, - token)) - , Coords(coords.GetDataAsMultiplexer().PrepareForInput(DeviceAdapter{}, token)) - { - } - - VTKM_EXEC_CONT virtual ~CellLocatorUniformBins() noexcept override - { - // This must not be defaulted, since defaulted virtual destructors are - // troublesome with CUDA __host__ __device__ markup. - } - - VTKM_EXEC - vtkm::ErrorCode FindCell(const FloatVec3& point, - vtkm::Id& cellId, - FloatVec3& parametric) const override - { - using namespace vtkm::internal::cl_uniform_bins; - - cellId = -1; - - DimVec3 binId3 = static_cast((point - this->TopLevel.Origin) / this->TopLevel.BinSize); - if (binId3[0] >= 0 && binId3[0] < this->TopLevel.Dimensions[0] && binId3[1] >= 0 && - binId3[1] < this->TopLevel.Dimensions[1] && binId3[2] >= 0 && - binId3[2] < this->TopLevel.Dimensions[2]) - { - vtkm::Id binId = ComputeFlatIndex(binId3, this->TopLevel.Dimensions); - - auto ldim = this->LeafDimensions.Get(binId); - if (!ldim[0] || !ldim[1] || !ldim[2]) - { - return vtkm::ErrorCode::CellNotFound; - } - - auto leafGrid = ComputeLeafGrid(binId3, ldim, this->TopLevel); - - DimVec3 leafId3 = static_cast((point - leafGrid.Origin) / leafGrid.BinSize); - // precision issues may cause leafId3 to be out of range so clamp it - leafId3 = vtkm::Max(DimVec3(0), vtkm::Min(ldim - DimVec3(1), leafId3)); - - vtkm::Id leafStart = this->LeafStartIndex.Get(binId); - vtkm::Id leafId = leafStart + ComputeFlatIndex(leafId3, leafGrid.Dimensions); - - vtkm::Id start = this->CellStartIndex.Get(leafId); - vtkm::Id end = start + this->CellCount.Get(leafId); - for (vtkm::Id i = start; i < end; ++i) - { - vtkm::Id cid = this->CellIds.Get(i); - auto indices = this->CellSet.GetIndices(cid); - auto pts = vtkm::make_VecFromPortalPermute(&indices, this->Coords); - FloatVec3 pc; - bool inside; - VTKM_RETURN_ON_ERROR( - PointInsideCell(point, this->CellSet.GetCellShape(cid), pts, pc, inside)); - if (inside) - { - cellId = cid; - parametric = pc; - return vtkm::ErrorCode::Success; - } - } - } - - return vtkm::ErrorCode::CellNotFound; - } - -private: - vtkm::internal::cl_uniform_bins::Grid TopLevel; - - ArrayPortalConst LeafDimensions; - ArrayPortalConst LeafStartIndex; - - ArrayPortalConst CellStartIndex; - ArrayPortalConst CellCount; - ArrayPortalConst CellIds; - - CellSetP2CExecType CellSet; - CoordsPortalType Coords; -}; -} -} // vtkm::exec +#include +#include namespace vtkm { namespace cont { -//---------------------------------------------------------------------------- -class VTKM_CONT_EXPORT CellLocatorUniformBins : public vtkm::cont::CellLocator +struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Replaced with CellLocatorTwoLevel.") + CellLocatorUniformBins : vtkm::cont::CellLocatorTwoLevel { -public: - CellLocatorUniformBins() - : DensityL1(32.0f) - , DensityL2(2.0f) - { - } - - /// Get/Set the desired approximate number of cells per level 1 bin - /// - void SetDensityL1(vtkm::FloatDefault val) - { - this->DensityL1 = val; - this->SetModified(); - } - vtkm::FloatDefault GetDensityL1() const { return this->DensityL1; } - - /// Get/Set the desired approximate number of cells per level 1 bin - /// - void SetDensityL2(vtkm::FloatDefault val) - { - this->DensityL2 = val; - this->SetModified(); - } - vtkm::FloatDefault GetDensityL2() const { return this->DensityL2; } - - void PrintSummary(std::ostream& out) const; - - const vtkm::exec::CellLocator* PrepareForExecution(vtkm::cont::DeviceAdapterId device, - vtkm::cont::Token& token) const override; - -private: - VTKM_CONT void Build() override; - - vtkm::FloatDefault DensityL1, DensityL2; - - vtkm::internal::cl_uniform_bins::Grid TopLevel; - vtkm::cont::ArrayHandle LeafDimensions; - vtkm::cont::ArrayHandle LeafStartIndex; - vtkm::cont::ArrayHandle CellStartIndex; - vtkm::cont::ArrayHandle CellCount; - vtkm::cont::ArrayHandle CellIds; - - mutable vtkm::cont::VirtualObjectHandle ExecutionObjectHandle; - - struct MakeExecObject; - struct PrepareForExecutionFunctor; }; -} -} // vtkm::cont -#endif // vtk_m_cont_CellLocatorUniformBins_h +} +} // namespace vtkm::cont + +#endif //vtk_m_cont_CellLocatorUniformBins_h diff --git a/vtkm/cont/cuda/testing/CMakeLists.txt b/vtkm/cont/cuda/testing/CMakeLists.txt index 398abacf5..7448a1461 100644 --- a/vtkm/cont/cuda/testing/CMakeLists.txt +++ b/vtkm/cont/cuda/testing/CMakeLists.txt @@ -14,7 +14,7 @@ set(unit_tests UnitTestCudaArrayHandleMultiplexer.cu UnitTestCudaBitField.cu UnitTestCudaCellLocatorRectilinearGrid.cu - UnitTestCudaCellLocatorUniformBins.cu + UnitTestCudaCellLocatorTwoLevel.cu UnitTestCudaCellLocatorUniformGrid.cu UnitTestCudaComputeRange.cu UnitTestCudaColorTable.cu diff --git a/vtkm/cont/cuda/testing/UnitTestCudaCellLocatorUniformBins.cu b/vtkm/cont/cuda/testing/UnitTestCudaCellLocatorTwoLevel.cu similarity index 75% rename from vtkm/cont/cuda/testing/UnitTestCudaCellLocatorUniformBins.cu rename to vtkm/cont/cuda/testing/UnitTestCudaCellLocatorTwoLevel.cu index 41d6f1f96..068bb5bb2 100644 --- a/vtkm/cont/cuda/testing/UnitTestCudaCellLocatorUniformBins.cu +++ b/vtkm/cont/cuda/testing/UnitTestCudaCellLocatorTwoLevel.cu @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include -int UnitTestCudaCellLocatorUniformBins(int argc, char* argv[]) +int UnitTestCudaCellLocatorTwoLevel(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{}); return vtkm::cont::testing::Testing::Run( - TestingCellLocatorUniformBins, argc, argv); + TestingCellLocatorTwoLevel, argc, argv); } diff --git a/vtkm/cont/kokkos/testing/CMakeLists.txt b/vtkm/cont/kokkos/testing/CMakeLists.txt index e6907f4f7..2377a9703 100644 --- a/vtkm/cont/kokkos/testing/CMakeLists.txt +++ b/vtkm/cont/kokkos/testing/CMakeLists.txt @@ -14,7 +14,7 @@ set(unit_tests UnitTestKokkosArrayHandleMultiplexer.cxx UnitTestKokkosBitField.cxx UnitTestKokkosCellLocatorRectilinearGrid.cxx - UnitTestKokkosCellLocatorUniformBins.cxx + UnitTestKokkosCellLocatorTwoLevel.cxx UnitTestKokkosCellLocatorUniformGrid.cxx UnitTestKokkosComputeRange.cxx UnitTestKokkosColorTable.cxx diff --git a/vtkm/cont/kokkos/testing/UnitTestKokkosCellLocatorUniformBins.cxx b/vtkm/cont/kokkos/testing/UnitTestKokkosCellLocatorTwoLevel.cxx similarity index 74% rename from vtkm/cont/kokkos/testing/UnitTestKokkosCellLocatorUniformBins.cxx rename to vtkm/cont/kokkos/testing/UnitTestKokkosCellLocatorTwoLevel.cxx index f6167b3fb..d0555104f 100644 --- a/vtkm/cont/kokkos/testing/UnitTestKokkosCellLocatorUniformBins.cxx +++ b/vtkm/cont/kokkos/testing/UnitTestKokkosCellLocatorTwoLevel.cxx @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include -int UnitTestKokkosCellLocatorUniformBins(int argc, char* argv[]) +int UnitTestKokkosCellLocatorTwoLevel(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagKokkos{}); return vtkm::cont::testing::Testing::Run( - TestingCellLocatorUniformBins, argc, argv); + TestingCellLocatorTwoLevel, argc, argv); } diff --git a/vtkm/cont/openmp/testing/CMakeLists.txt b/vtkm/cont/openmp/testing/CMakeLists.txt index 5dfea2669..8951dae11 100644 --- a/vtkm/cont/openmp/testing/CMakeLists.txt +++ b/vtkm/cont/openmp/testing/CMakeLists.txt @@ -14,7 +14,7 @@ set(unit_tests UnitTestOpenMPArrayHandleMultiplexer.cxx UnitTestOpenMPBitField.cxx UnitTestOpenMPCellLocatorRectilinearGrid.cxx - UnitTestOpenMPCellLocatorUniformBins.cxx + UnitTestOpenMPCellLocatorTwoLevel.cxx UnitTestOpenMPCellLocatorUniformGrid.cxx UnitTestOpenMPColorTable.cxx UnitTestOpenMPComputeRange.cxx diff --git a/vtkm/cont/openmp/testing/UnitTestOpenMPCellLocatorUniformBins.cxx b/vtkm/cont/openmp/testing/UnitTestOpenMPCellLocatorTwoLevel.cxx similarity index 76% rename from vtkm/cont/openmp/testing/UnitTestOpenMPCellLocatorUniformBins.cxx rename to vtkm/cont/openmp/testing/UnitTestOpenMPCellLocatorTwoLevel.cxx index ebdcaaf37..ad1d3c93e 100644 --- a/vtkm/cont/openmp/testing/UnitTestOpenMPCellLocatorUniformBins.cxx +++ b/vtkm/cont/openmp/testing/UnitTestOpenMPCellLocatorTwoLevel.cxx @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ #include -#include +#include -int UnitTestOpenMPCellLocatorUniformBins(int argc, char* argv[]) +int UnitTestOpenMPCellLocatorTwoLevel(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{}); return vtkm::cont::testing::Testing::Run( - TestingCellLocatorUniformBins, argc, argv); + TestingCellLocatorTwoLevel, argc, argv); } diff --git a/vtkm/cont/serial/testing/CMakeLists.txt b/vtkm/cont/serial/testing/CMakeLists.txt index 433a34a49..123e97ed3 100644 --- a/vtkm/cont/serial/testing/CMakeLists.txt +++ b/vtkm/cont/serial/testing/CMakeLists.txt @@ -14,7 +14,7 @@ set(unit_tests UnitTestSerialArrayHandleMultiplexer.cxx UnitTestSerialBitField.cxx UnitTestSerialCellLocatorRectilinearGrid.cxx - UnitTestSerialCellLocatorUniformBins.cxx + UnitTestSerialCellLocatorTwoLevel.cxx UnitTestSerialCellLocatorUniformGrid.cxx UnitTestSerialComputeRange.cxx UnitTestSerialColorTable.cxx diff --git a/vtkm/cont/serial/testing/UnitTestSerialCellLocatorUniformBins.cxx b/vtkm/cont/serial/testing/UnitTestSerialCellLocatorTwoLevel.cxx similarity index 76% rename from vtkm/cont/serial/testing/UnitTestSerialCellLocatorUniformBins.cxx rename to vtkm/cont/serial/testing/UnitTestSerialCellLocatorTwoLevel.cxx index eaf9973b0..a4b1cd90e 100644 --- a/vtkm/cont/serial/testing/UnitTestSerialCellLocatorUniformBins.cxx +++ b/vtkm/cont/serial/testing/UnitTestSerialCellLocatorTwoLevel.cxx @@ -9,12 +9,12 @@ //============================================================================ #include -#include +#include -int UnitTestSerialCellLocatorUniformBins(int argc, char* argv[]) +int UnitTestSerialCellLocatorTwoLevel(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagSerial{}); return vtkm::cont::testing::Testing::Run( - TestingCellLocatorUniformBins, argc, argv); + TestingCellLocatorTwoLevel, argc, argv); } diff --git a/vtkm/cont/tbb/testing/CMakeLists.txt b/vtkm/cont/tbb/testing/CMakeLists.txt index e6c3726f7..f705c5180 100644 --- a/vtkm/cont/tbb/testing/CMakeLists.txt +++ b/vtkm/cont/tbb/testing/CMakeLists.txt @@ -14,7 +14,7 @@ set(unit_tests UnitTestTBBArrayHandleMultiplexer.cxx UnitTestTBBBitField.cxx UnitTestTBBCellLocatorRectilinearGrid.cxx - UnitTestTBBCellLocatorUniformBins.cxx + UnitTestTBBCellLocatorTwoLevel.cxx UnitTestTBBCellLocatorUniformGrid.cxx UnitTestTBBColorTable.cxx UnitTestTBBComputeRange.cxx diff --git a/vtkm/cont/tbb/testing/UnitTestTBBCellLocatorUniformBins.cxx b/vtkm/cont/tbb/testing/UnitTestTBBCellLocatorTwoLevel.cxx similarity index 75% rename from vtkm/cont/tbb/testing/UnitTestTBBCellLocatorUniformBins.cxx rename to vtkm/cont/tbb/testing/UnitTestTBBCellLocatorTwoLevel.cxx index 978002632..627cb17ea 100644 --- a/vtkm/cont/tbb/testing/UnitTestTBBCellLocatorUniformBins.cxx +++ b/vtkm/cont/tbb/testing/UnitTestTBBCellLocatorTwoLevel.cxx @@ -8,12 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include -int UnitTestTBBCellLocatorUniformBins(int argc, char* argv[]) +int UnitTestTBBCellLocatorTwoLevel(int argc, char* argv[]) { auto& tracker = vtkm::cont::GetRuntimeDeviceTracker(); tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{}); return vtkm::cont::testing::Testing::Run( - TestingCellLocatorUniformBins, argc, argv); + TestingCellLocatorTwoLevel, argc, argv); } diff --git a/vtkm/cont/testing/CMakeLists.txt b/vtkm/cont/testing/CMakeLists.txt index fbb04c7dd..6ed6c21a7 100644 --- a/vtkm/cont/testing/CMakeLists.txt +++ b/vtkm/cont/testing/CMakeLists.txt @@ -15,7 +15,7 @@ set(headers TestingArrayHandles.h TestingArrayHandleMultiplexer.h TestingCellLocatorRectilinearGrid.h - TestingCellLocatorUniformBins.h + TestingCellLocatorTwoLevel.h TestingCellLocatorUniformGrid.h TestingColorTable.h TestingComputeRange.h diff --git a/vtkm/cont/testing/TestingCellLocatorUniformBins.h b/vtkm/cont/testing/TestingCellLocatorTwoLevel.h similarity index 96% rename from vtkm/cont/testing/TestingCellLocatorUniformBins.h rename to vtkm/cont/testing/TestingCellLocatorTwoLevel.h index 8ea423f1e..b8c73b36e 100644 --- a/vtkm/cont/testing/TestingCellLocatorUniformBins.h +++ b/vtkm/cont/testing/TestingCellLocatorTwoLevel.h @@ -7,11 +7,11 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_cont_testing_TestingCellLocatorUniformBins_h -#define vtk_m_cont_testing_TestingCellLocatorUniformBins_h +#ifndef vtk_m_cont_testing_TestingCellLocatorTwoLevel_h +#define vtk_m_cont_testing_TestingCellLocatorTwoLevel_h #include -#include +#include #include #include @@ -188,7 +188,7 @@ void TestCellLocator(const vtkm::Vec& dim, vtkm::Id number std::cout << "Testing " << DIMENSIONS << "D dataset with " << ds.GetNumberOfCells() << " cells\n"; - vtkm::cont::CellLocatorUniformBins locator; + vtkm::cont::CellLocatorTwoLevel locator; locator.SetDensityL1(64.0f); locator.SetDensityL2(1.0f); locator.SetCellSet(ds.GetCellSet()); @@ -222,7 +222,7 @@ void TestCellLocator(const vtkm::Vec& dim, vtkm::Id number } // anonymous template -void TestingCellLocatorUniformBins() +void TestingCellLocatorTwoLevel() { vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(DeviceAdapter()); @@ -234,4 +234,4 @@ void TestingCellLocatorUniformBins() TestCellLocator(vtkm::Id2(18), 512); // 2D dataset } -#endif // vtk_m_cont_testing_TestingCellLocatorUniformBins_h +#endif // vtk_m_cont_testing_TestingCellLocatorTwoLevel_h diff --git a/vtkm/exec/CMakeLists.txt b/vtkm/exec/CMakeLists.txt index 93f74fe86..ecf68f1fc 100644 --- a/vtkm/exec/CMakeLists.txt +++ b/vtkm/exec/CMakeLists.txt @@ -19,6 +19,7 @@ set(headers CellLocator.h CellLocatorBoundingIntervalHierarchyExec.h CellLocatorRectilinearGrid.h + CellLocatorTwoLevel.h CellLocatorUniformGrid.h CellMeasure.h ColorTable.h diff --git a/vtkm/exec/CellLocatorTwoLevel.h b/vtkm/exec/CellLocatorTwoLevel.h new file mode 100644 index 000000000..3dd9132c0 --- /dev/null +++ b/vtkm/exec/CellLocatorTwoLevel.h @@ -0,0 +1,229 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#ifndef vtk_m_exec_CellLocatorTwoLevel_h +#define vtk_m_exec_CellLocatorTwoLevel_h + +#include +#include + +#include +#include +#include +#include + +namespace vtkm +{ +namespace internal +{ +namespace cl_uniform_bins +{ + +using DimensionType = vtkm::Int16; +using DimVec3 = vtkm::Vec; +using FloatVec3 = vtkm::Vec3f; + +struct Grid +{ + DimVec3 Dimensions; + FloatVec3 Origin; + FloatVec3 BinSize; +}; + +struct Bounds +{ + FloatVec3 Min; + FloatVec3 Max; +}; + +VTKM_EXEC inline vtkm::Id ComputeFlatIndex(const DimVec3& idx, const DimVec3 dim) +{ + return idx[0] + (dim[0] * (idx[1] + (dim[1] * idx[2]))); +} + +VTKM_EXEC inline Grid ComputeLeafGrid(const DimVec3& idx, const DimVec3& dim, const Grid& l1Grid) +{ + return { dim, + l1Grid.Origin + (static_cast(idx) * l1Grid.BinSize), + l1Grid.BinSize / static_cast(dim) }; +} + +template +VTKM_EXEC inline Bounds ComputeCellBounds(const PointsVecType& points) +{ + using CoordsType = typename vtkm::VecTraits::ComponentType; + auto numPoints = vtkm::VecTraits::GetNumberOfComponents(points); + + CoordsType minp = points[0], maxp = points[0]; + for (vtkm::IdComponent i = 1; i < numPoints; ++i) + { + minp = vtkm::Min(minp, points[i]); + maxp = vtkm::Max(maxp, points[i]); + } + + return { FloatVec3(minp), FloatVec3(maxp) }; +} +} +} +} // vtkm::internal::cl_uniform_bins + +namespace vtkm +{ +namespace exec +{ + +//-------------------------------------------------------------------- +template +class VTKM_ALWAYS_EXPORT CellLocatorTwoLevel : public vtkm::exec::CellLocator +{ +private: + using DimVec3 = vtkm::internal::cl_uniform_bins::DimVec3; + using FloatVec3 = vtkm::internal::cl_uniform_bins::FloatVec3; + + template + using ArrayPortalConst = + typename vtkm::cont::ArrayHandle::template ExecutionTypes::PortalConst; + + using CoordsPortalType = + typename vtkm::cont::CoordinateSystem::MultiplexerArrayType::ExecutionTypes< + DeviceAdapter>::PortalConst; + + using CellSetP2CExecType = + decltype(std::declval().PrepareForInput(DeviceAdapter{}, + vtkm::TopologyElementTagCell{}, + vtkm::TopologyElementTagPoint{}, + std::declval())); + + // TODO: This function may return false positives for non 3D cells as the + // tests are done on the projection of the point on the cell. Extra checks + // should be added to test if the point actually falls on the cell. + template + VTKM_EXEC static vtkm::ErrorCode PointInsideCell(FloatVec3 point, + CellShapeTag cellShape, + CoordsType cellPoints, + FloatVec3& parametricCoordinates, + bool& inside) + { + auto bounds = vtkm::internal::cl_uniform_bins::ComputeCellBounds(cellPoints); + if (point[0] >= bounds.Min[0] && point[0] <= bounds.Max[0] && point[1] >= bounds.Min[1] && + point[1] <= bounds.Max[1] && point[2] >= bounds.Min[2] && point[2] <= bounds.Max[2]) + { + VTKM_RETURN_ON_ERROR(vtkm::exec::WorldCoordinatesToParametricCoordinates( + cellPoints, point, cellShape, parametricCoordinates)); + inside = vtkm::exec::CellInside(parametricCoordinates, cellShape); + } + else + { + inside = false; + } + // Return success error code even point is not inside this cell + return vtkm::ErrorCode::Success; + } + +public: + VTKM_CONT CellLocatorTwoLevel(const vtkm::internal::cl_uniform_bins::Grid& topLevelGrid, + const vtkm::cont::ArrayHandle& leafDimensions, + const vtkm::cont::ArrayHandle& leafStartIndex, + const vtkm::cont::ArrayHandle& cellStartIndex, + const vtkm::cont::ArrayHandle& cellCount, + const vtkm::cont::ArrayHandle& cellIds, + const CellSetType& cellSet, + const vtkm::cont::CoordinateSystem& coords, + vtkm::cont::Token& token) + : TopLevel(topLevelGrid) + , LeafDimensions(leafDimensions.PrepareForInput(DeviceAdapter{}, token)) + , LeafStartIndex(leafStartIndex.PrepareForInput(DeviceAdapter{}, token)) + , CellStartIndex(cellStartIndex.PrepareForInput(DeviceAdapter{}, token)) + , CellCount(cellCount.PrepareForInput(DeviceAdapter{}, token)) + , CellIds(cellIds.PrepareForInput(DeviceAdapter{}, token)) + , CellSet(cellSet.PrepareForInput(DeviceAdapter{}, + vtkm::TopologyElementTagCell{}, + vtkm::TopologyElementTagPoint{}, + token)) + , Coords(coords.GetDataAsMultiplexer().PrepareForInput(DeviceAdapter{}, token)) + { + } + + VTKM_EXEC_CONT virtual ~CellLocatorTwoLevel() noexcept override + { + // This must not be defaulted, since defaulted virtual destructors are + // troublesome with CUDA __host__ __device__ markup. + } + + VTKM_EXEC + vtkm::ErrorCode FindCell(const FloatVec3& point, + vtkm::Id& cellId, + FloatVec3& parametric) const override + { + using namespace vtkm::internal::cl_uniform_bins; + + cellId = -1; + + DimVec3 binId3 = static_cast((point - this->TopLevel.Origin) / this->TopLevel.BinSize); + if (binId3[0] >= 0 && binId3[0] < this->TopLevel.Dimensions[0] && binId3[1] >= 0 && + binId3[1] < this->TopLevel.Dimensions[1] && binId3[2] >= 0 && + binId3[2] < this->TopLevel.Dimensions[2]) + { + vtkm::Id binId = ComputeFlatIndex(binId3, this->TopLevel.Dimensions); + + auto ldim = this->LeafDimensions.Get(binId); + if (!ldim[0] || !ldim[1] || !ldim[2]) + { + return vtkm::ErrorCode::CellNotFound; + } + + auto leafGrid = ComputeLeafGrid(binId3, ldim, this->TopLevel); + + DimVec3 leafId3 = static_cast((point - leafGrid.Origin) / leafGrid.BinSize); + // precision issues may cause leafId3 to be out of range so clamp it + leafId3 = vtkm::Max(DimVec3(0), vtkm::Min(ldim - DimVec3(1), leafId3)); + + vtkm::Id leafStart = this->LeafStartIndex.Get(binId); + vtkm::Id leafId = leafStart + ComputeFlatIndex(leafId3, leafGrid.Dimensions); + + vtkm::Id start = this->CellStartIndex.Get(leafId); + vtkm::Id end = start + this->CellCount.Get(leafId); + for (vtkm::Id i = start; i < end; ++i) + { + vtkm::Id cid = this->CellIds.Get(i); + auto indices = this->CellSet.GetIndices(cid); + auto pts = vtkm::make_VecFromPortalPermute(&indices, this->Coords); + FloatVec3 pc; + bool inside; + VTKM_RETURN_ON_ERROR( + PointInsideCell(point, this->CellSet.GetCellShape(cid), pts, pc, inside)); + if (inside) + { + cellId = cid; + parametric = pc; + return vtkm::ErrorCode::Success; + } + } + } + + return vtkm::ErrorCode::CellNotFound; + } + +private: + vtkm::internal::cl_uniform_bins::Grid TopLevel; + + ArrayPortalConst LeafDimensions; + ArrayPortalConst LeafStartIndex; + + ArrayPortalConst CellStartIndex; + ArrayPortalConst CellCount; + ArrayPortalConst CellIds; + + CellSetP2CExecType CellSet; + CoordsPortalType Coords; +}; +} +} // vtkm::exec + +#endif //vtk_m_exec_CellLocatorTwoLevel_h diff --git a/vtkm/worklet/particleadvection/GridEvaluatorStatus.h b/vtkm/worklet/particleadvection/GridEvaluatorStatus.h index f7c0173b5..3f3e427e3 100644 --- a/vtkm/worklet/particleadvection/GridEvaluatorStatus.h +++ b/vtkm/worklet/particleadvection/GridEvaluatorStatus.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/vtkm/worklet/particleadvection/GridEvaluators.h b/vtkm/worklet/particleadvection/GridEvaluators.h index e9a1f8dba..7a4bcb8d7 100644 --- a/vtkm/worklet/particleadvection/GridEvaluators.h +++ b/vtkm/worklet/particleadvection/GridEvaluators.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -167,11 +167,11 @@ public: else { // Default to using an locator for explicit meshes. - vtkm::cont::CellLocatorUniformBins locator; + vtkm::cont::CellLocatorTwoLevel locator; locator.SetCoordinates(coordinates); locator.SetCellSet(cellset); locator.Update(); - this->Locator = std::make_shared(locator); + this->Locator = std::make_shared(locator); } vtkm::cont::StructuredCellInterpolationHelper interpolationHelper(cellset); this->InterpolationHelper = @@ -179,22 +179,22 @@ public: } else if (cellset.IsSameType(vtkm::cont::CellSetSingleType<>())) { - vtkm::cont::CellLocatorUniformBins locator; + vtkm::cont::CellLocatorTwoLevel locator; locator.SetCoordinates(coordinates); locator.SetCellSet(cellset); locator.Update(); - this->Locator = std::make_shared(locator); + this->Locator = std::make_shared(locator); vtkm::cont::SingleCellTypeInterpolationHelper interpolationHelper(cellset); this->InterpolationHelper = std::make_shared(interpolationHelper); } else if (cellset.IsSameType(vtkm::cont::CellSetExplicit<>())) { - vtkm::cont::CellLocatorUniformBins locator; + vtkm::cont::CellLocatorTwoLevel locator; locator.SetCoordinates(coordinates); locator.SetCellSet(cellset); locator.Update(); - this->Locator = std::make_shared(locator); + this->Locator = std::make_shared(locator); vtkm::cont::ExplicitCellInterpolationHelper interpolationHelper(cellset); this->InterpolationHelper = std::make_shared(interpolationHelper); From 2278fdfd94ed0d9a9125b93108c409f3f38bb68a Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 23 Sep 2020 10:02:37 -0400 Subject: [PATCH 45/51] Deprecation macro has to come before VTKM_EXEC or VTKM_EXEC_CONT This order is needed by CUDA-clang and HIP-clang compilers --- docs/changelog/deprecation.md | 6 +++--- vtkm/exec/CellLocator.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/changelog/deprecation.md b/docs/changelog/deprecation.md index 1c8f61b7c..68bbc65aa 100644 --- a/docs/changelog/deprecation.md +++ b/docs/changelog/deprecation.md @@ -40,11 +40,11 @@ using OldAlias VTKM_DEPRECATED(1.6, "Use NewClass instead.") = NewClass; ``` Functions and methods are marked as deprecated by adding `VTKM_DEPRECATED` -as a modifier before the return value. +as a modifier before the return value and any markup (VTKM_CONT, VTKM_EXEC, or VTKM_EXEC_CONT). ``` cpp -VTKM_EXEC_CONT VTKM_DEPRECATED(1.6, "You must now specify a tolerance.") void ImportantMethod(double x) +VTKM_EXEC_CONT { this->ImportantMethod(x, 1e-6); } @@ -83,8 +83,8 @@ support this a pair of macros, `VTKM_DEPRECATED_SUPPRESS_BEGIN` and deprecated items should be wrapped in these macros. ``` cpp -VTKM_EXEC_CONT VTKM_DEPRECATED(1.6, "You must now specify both a value and tolerance.") +VTKM_EXEC_CONT void ImportantMethod() { // It can be the case that to implement a deprecated method you need to diff --git a/vtkm/exec/CellLocator.h b/vtkm/exec/CellLocator.h index 6137e693e..f81601d5b 100644 --- a/vtkm/exec/CellLocator.h +++ b/vtkm/exec/CellLocator.h @@ -35,8 +35,8 @@ public: vtkm::Id& cellId, vtkm::Vec3f& parametric) const = 0; - VTKM_EXEC VTKM_DEPRECATED(1.6, "FindCell no longer takes worklet argument.") + VTKM_EXEC void FindCell(const vtkm::Vec3f& point, vtkm::Id& cellId, vtkm::Vec3f& parametric, From 461616a771f7849a184be12008fda0f5aca4d176 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 16 Sep 2020 09:36:28 -0400 Subject: [PATCH 46/51] Refactor some VTK-m device adapter to be alphabetical --- CMake/VTKmConfig.cmake.in | 4 ++-- CMakeLists.txt | 4 ++-- vtkm/internal/CMakeLists.txt | 14 +++----------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/CMake/VTKmConfig.cmake.in b/CMake/VTKmConfig.cmake.in index 3097e7a1e..05b81592c 100644 --- a/CMake/VTKmConfig.cmake.in +++ b/CMake/VTKmConfig.cmake.in @@ -68,9 +68,9 @@ set(VTKm_VERSION "@VTKm_VERSION@") set(VTKm_BUILD_SHARED_LIBS "@VTKm_BUILD_SHARED_LIBS@") set(VTKm_ENABLE_CUDA "@VTKm_ENABLE_CUDA@") -set(VTKm_ENABLE_TBB "@VTKm_ENABLE_TBB@") -set(VTKm_ENABLE_OPENMP "@VTKm_ENABLE_OPENMP@") set(VTKm_ENABLE_KOKKOS "@VTKm_ENABLE_KOKKOS@") +set(VTKm_ENABLE_OPENMP "@VTKm_ENABLE_OPENMP@") +set(VTKm_ENABLE_TBB "@VTKm_ENABLE_TBB@") set(VTKm_ENABLE_LOGGING "@VTKm_ENABLE_LOGGING@") set(VTKm_ENABLE_RENDERING "@VTKm_ENABLE_RENDERING@") set(VTKm_ENABLE_GL_CONTEXT "@VTKm_ENABLE_GL_CONTEXT@") diff --git a/CMakeLists.txt b/CMakeLists.txt index e907495f3..8b12223d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,9 +73,9 @@ endmacro () # Configurable Options vtkm_option(VTKm_ENABLE_CUDA "Enable Cuda support" OFF) -vtkm_option(VTKm_ENABLE_TBB "Enable TBB support" OFF) -vtkm_option(VTKm_ENABLE_OPENMP "Enable OpenMP support" OFF) vtkm_option(VTKm_ENABLE_KOKKOS "Enable Kokkos support" OFF) +vtkm_option(VTKm_ENABLE_OPENMP "Enable OpenMP support" OFF) +vtkm_option(VTKm_ENABLE_TBB "Enable TBB support" OFF) vtkm_option(VTKm_ENABLE_RENDERING "Enable rendering library" ON) vtkm_option(VTKm_ENABLE_BENCHMARKS "Enable VTKm Benchmarking" OFF) vtkm_option(VTKm_ENABLE_MPI "Enable MPI support" OFF) diff --git a/vtkm/internal/CMakeLists.txt b/vtkm/internal/CMakeLists.txt index 2019eb291..4224aaa2c 100755 --- a/vtkm/internal/CMakeLists.txt +++ b/vtkm/internal/CMakeLists.txt @@ -19,9 +19,10 @@ set(VTKM_USE_DOUBLE_PRECISION ${VTKm_USE_DOUBLE_PRECISION}) set(VTKM_USE_64BIT_IDS ${VTKm_USE_64BIT_IDS}) set(VTKM_ENABLE_CUDA ${VTKm_ENABLE_CUDA}) -set(VTKM_ENABLE_TBB ${VTKm_ENABLE_TBB}) -set(VTKM_ENABLE_OPENMP ${VTKm_ENABLE_OPENMP}) set(VTKM_ENABLE_KOKKOS ${VTKm_ENABLE_KOKKOS}) +set(VTKM_ENABLE_OPENMP ${VTKm_ENABLE_OPENMP}) +set(VTKM_ENABLE_TBB ${VTKm_ENABLE_TBB}) + set(VTKM_ENABLE_MPI ${VTKm_ENABLE_MPI}) if(VTKM_ENABLE_CUDA) @@ -34,7 +35,6 @@ if (TARGET vtkm::kokkos_cuda) endif() set(VTKM_ENABLE_LOGGING ${VTKm_ENABLE_LOGGING}) - set(VTKM_NO_DEPRECATED_VIRTUAL ${VTKm_NO_DEPRECATED_VIRTUAL}) vtkm_get_kit_name(kit_name kit_dir) @@ -45,14 +45,6 @@ vtkm_install_headers(vtkm/internal ${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/Configure.h ) -unset(VTKM_ENABLE_MPI) -unset(VTKM_ENABLE_TBB) -unset(VTKM_ENABLE_CUDA) - -unset(VTKM_USE_64BIT_IDS) -unset(VTKM_USE_DOUBLE_PRECISION) -unset(VTKM_NO_ASSERT) - set(headers ArrayPortalBasic.h From 09df45bb191dcc6209728f03f494539b3b165ed5 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 16 Sep 2020 15:44:20 -0400 Subject: [PATCH 47/51] Update vtkm/Geometry.hxx to follow clangs rules on function markup --- vtkm/Geometry.hxx | 143 +++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 73 deletions(-) diff --git a/vtkm/Geometry.hxx b/vtkm/Geometry.hxx index c766d32dd..bc9cdc41d 100644 --- a/vtkm/Geometry.hxx +++ b/vtkm/Geometry.hxx @@ -16,7 +16,7 @@ namespace vtkm template template ::type> -Ray::Ray() +VTKM_EXEC_CONT Ray::Ray() : Origin{ 0.f } , Direction{ 1.f, 0.f } { @@ -24,50 +24,42 @@ Ray::Ray() template template ::type> -Ray::Ray() +VTKM_EXEC_CONT Ray::Ray() : Origin{ 0.f } , Direction{ 1.f, 0.f, 0.f } { } template -Ray::Ray(const LineSegment& segment) +VTKM_EXEC_CONT Ray::Ray(const LineSegment& segment) : Origin(segment.Endpoints[0]) , Direction(vtkm::Normal(segment.Direction())) { } template -Ray::Ray(const Vector& point, const Vector& direction) +VTKM_EXEC_CONT Ray::Ray(const Vector& point, const Vector& direction) : Origin(point) , Direction(vtkm::Normal(direction)) { } template -typename Ray::Vector Ray::Evaluate( - CoordType param) const +VTKM_EXEC_CONT typename Ray::Vector +Ray::Evaluate(CoordType param) const { auto pointOnLine = this->Origin + this->Direction * param; return pointOnLine; } template -bool Ray::IsValid() const +VTKM_EXEC_CONT bool Ray::IsValid() const { -// At least on Ubuntu 17.10, cuda 9.1 will fail with an internal -// compiler error when calling vtkm::IsInf() here. But the fix -// below works. The fix should be removed as soon as our dashboards -// allow it. -#if __CUDACC_VER_MAJOR__ == 9 && __CUDACC_VER_MINOR__ == 1 - return !isinf(this->Direction[0]); -#else return !vtkm::IsInf(this->Direction[0]); -#endif } template -CoordType Ray::DistanceTo(const Vector& point) const +VTKM_EXEC_CONT CoordType Ray::DistanceTo(const Vector& point) const { Vector closest; CoordType param; @@ -75,9 +67,9 @@ CoordType Ray::DistanceTo(const Vector& point) const } template -CoordType Ray::DistanceTo(const Vector& point, - CoordType& param, - Vector& projectedPoint) const +VTKM_EXEC_CONT CoordType Ray::DistanceTo(const Vector& point, + CoordType& param, + Vector& projectedPoint) const { const auto& dir = this->Direction; auto mag2 = vtkm::MagnitudeSquared(dir); @@ -105,9 +97,10 @@ CoordType Ray::DistanceTo(const Vector& point, template template ::type> -bool Ray::Intersect(const Ray& other, - Vector& point, - CoordType tol) +VTKM_EXEC_CONT bool Ray::Intersect( + const Ray& other, + Vector& point, + CoordType tol) { auto d1 = this->Direction; auto d2 = other.Direction; @@ -139,33 +132,33 @@ bool Ray::Intersect(const Ray template ::type> -LineSegment::LineSegment() +VTKM_EXEC_CONT LineSegment::LineSegment() : Endpoints{ { 0.f }, { 1.f, 0.f } } { } template template ::type> -LineSegment::LineSegment() +VTKM_EXEC_CONT LineSegment::LineSegment() : Endpoints{ { 0.f }, { 1.f, 0.f, 0.f } } { } template -LineSegment::LineSegment(const Vector& p0, const Vector& p1) +VTKM_EXEC_CONT LineSegment::LineSegment(const Vector& p0, const Vector& p1) : Endpoints{ p0, p1 } { } template -bool LineSegment::IsSingular(CoordType tol2) const +VTKM_EXEC_CONT bool LineSegment::IsSingular(CoordType tol2) const { return vtkm::MagnitudeSquared(this->Direction()) < tol2; } template template ::type> -Ray LineSegment::PerpendicularBisector() const +VTKM_EXEC_CONT Ray LineSegment::PerpendicularBisector() const { const Vector dir = this->Direction(); const Vector perp(-dir[1], dir[0]); @@ -175,13 +168,13 @@ Ray LineSegment::PerpendicularBisector() c template template ::type> -Plane LineSegment::PerpendicularBisector() const +VTKM_EXEC_CONT Plane LineSegment::PerpendicularBisector() const { return Plane(this->Center(), this->Direction()); } template -typename LineSegment::Vector LineSegment::Evaluate( +VTKM_EXEC_CONT typename LineSegment::Vector LineSegment::Evaluate( CoordType param) const { auto pointOnLine = this->Endpoints[0] * (1.0f - param) + this->Endpoints[1] * param; @@ -189,7 +182,7 @@ typename LineSegment::Vector LineSegment::Evalua } template -CoordType LineSegment::DistanceTo(const Vector& point) const +VTKM_EXEC_CONT CoordType LineSegment::DistanceTo(const Vector& point) const { Vector closest; CoordType param; @@ -197,9 +190,9 @@ CoordType LineSegment::DistanceTo(const Vector& point) const } template -CoordType LineSegment::DistanceTo(const Vector& point, - CoordType& param, - Vector& projectedPoint) const +VTKM_EXEC_CONT CoordType LineSegment::DistanceTo(const Vector& point, + CoordType& param, + Vector& projectedPoint) const { auto dir = this->Endpoints[1] - this->Endpoints[0]; auto mag2 = vtkm::MagnitudeSquared(dir); @@ -224,9 +217,10 @@ CoordType LineSegment::DistanceTo(const Vector& point, template template ::type> -bool LineSegment::IntersectInfinite(const LineSegment& other, - Vector& point, - CoordType tol) +VTKM_EXEC_CONT bool LineSegment::IntersectInfinite( + const LineSegment& other, + Vector& point, + CoordType tol) { auto d1 = this->Direction(); auto d2 = other.Direction(); @@ -249,14 +243,14 @@ bool LineSegment::IntersectInfinite(const LineSegment -Plane::Plane() +VTKM_EXEC_CONT VTKM_EXEC_CONT Plane::Plane() : Origin{ 0.f, 0.f, 0.f } , Normal{ 0.f, 0.f, 1.f } { } template -Plane::Plane(const Vector& origin, const Vector& normal, CoordType tol2) +VTKM_EXEC_CONT Plane::Plane(const Vector& origin, const Vector& normal, CoordType tol2) : Origin(origin) , Normal(vtkm::Normal(normal)) { @@ -268,14 +262,15 @@ Plane::Plane(const Vector& origin, const Vector& normal, CoordType to } template -CoordType Plane::DistanceTo(const Vector& point) const +VTKM_EXEC_CONT CoordType Plane::DistanceTo(const Vector& point) const { auto dist = vtkm::Dot(point - this->Origin, this->Normal); return dist; } template -typename Plane::Vector Plane::ClosestPoint(const Vector& point) const +VTKM_EXEC_CONT typename Plane::Vector Plane::ClosestPoint( + const Vector& point) const { auto vop = vtkm::Project(point - this->Origin, this->Normal); auto closest = point - vop; @@ -284,11 +279,11 @@ typename Plane::Vector Plane::ClosestPoint(const Vector& p template template -bool Plane::Intersect(const Ray& ray, - CoordType& parameter, - Vector& point, - bool& lineInPlane, - CoordType tol) const +VTKM_EXEC_CONT bool Plane::Intersect(const Ray& ray, + CoordType& parameter, + Vector& point, + bool& lineInPlane, + CoordType tol) const { CoordType d0 = this->DistanceTo(ray.Origin); CoordType dirDot = vtkm::Dot(this->Normal, ray.Direction); @@ -330,19 +325,19 @@ bool Plane::Intersect(const Ray& ray, } template -bool Plane::Intersect(const LineSegment& segment, - CoordType& parameter, - bool& lineInPlane) const +VTKM_EXEC_CONT bool Plane::Intersect(const LineSegment& segment, + CoordType& parameter, + bool& lineInPlane) const { Vector point; return this->Intersect(segment, parameter, point, lineInPlane); } template -bool Plane::Intersect(const LineSegment& segment, - CoordType& parameter, - Vector& point, - bool& lineInPlane) const +VTKM_EXEC_CONT bool Plane::Intersect(const LineSegment& segment, + CoordType& parameter, + Vector& point, + bool& lineInPlane) const { CoordType d0 = this->DistanceTo(segment.Endpoints[0]); CoordType d1 = this->DistanceTo(segment.Endpoints[1]); @@ -394,10 +389,10 @@ bool Plane::Intersect(const LineSegment& segment, } template -bool Plane::Intersect(const Plane& other, - Ray& ray, - bool& coincident, - CoordType tol2) const +VTKM_EXEC_CONT bool Plane::Intersect(const Plane& other, + Ray& ray, + bool& coincident, + CoordType tol2) const { auto dir = vtkm::Cross(this->Normal, other.Normal); auto mag2 = vtkm::MagnitudeSquared(dir); @@ -434,27 +429,27 @@ bool Plane::Intersect(const Plane& other, // Sphere template -Sphere::Sphere() +VTKM_EXEC_CONT Sphere::Sphere() : Center{ 0.f } , Radius(static_cast(1.f)) { } template -Sphere::Sphere(const Vector& center, CoordType radius) +VTKM_EXEC_CONT Sphere::Sphere(const Vector& center, CoordType radius) : Center(center) , Radius(radius <= 0.f ? static_cast(-1.0f) : radius) { } template -bool Sphere::Contains(const Vector& point, CoordType tol2) const +VTKM_EXEC_CONT bool Sphere::Contains(const Vector& point, CoordType tol2) const { return this->Classify(point, tol2) < 0; } template -int Sphere::Classify(const Vector& point, CoordType tol2) const +VTKM_EXEC_CONT int Sphere::Classify(const Vector& point, CoordType tol2) const { if (!this->IsValid()) { @@ -469,16 +464,17 @@ int Sphere::Classify(const Vector& point, CoordType tol2) const // Construction techniques template -vtkm::Plane make_PlaneFromPointAndLine(const vtkm::Vec& point, - const vtkm::Ray& ray, - CoordType tol2) +VTKM_EXEC_CONT vtkm::Plane make_PlaneFromPointAndLine( + const vtkm::Vec& point, + const vtkm::Ray& ray, + CoordType tol2) { auto tmpDir = point - ray.Origin; return vtkm::Plane(point, vtkm::Cross(ray.Direction, tmpDir), tol2); } template -vtkm::Plane make_PlaneFromPointAndLineSegment( +VTKM_EXEC_CONT vtkm::Plane make_PlaneFromPointAndLineSegment( const vtkm::Vec& point, const vtkm::LineSegment3& segment, CoordType tol2) @@ -488,10 +484,11 @@ vtkm::Plane make_PlaneFromPointAndLineSegment( } template -vtkm::Circle make_CircleFrom3Points(const typename vtkm::Vec& p0, - const typename vtkm::Vec& p1, - const typename vtkm::Vec& p2, - CoordType tol) +VTKM_EXEC_CONT vtkm::Circle make_CircleFrom3Points( + const typename vtkm::Vec& p0, + const typename vtkm::Vec& p1, + const typename vtkm::Vec& p2, + CoordType tol) { constexpr int Dim = 2; using Vector = typename vtkm::Circle::Vector; @@ -518,11 +515,11 @@ vtkm::Circle make_CircleFrom3Points(const typename vtkm::Vec -vtkm::Sphere make_SphereFrom4Points(const vtkm::Vec& a0, - const vtkm::Vec& a1, - const vtkm::Vec& a2, - const vtkm::Vec& a3, - CoordType tol) +VTKM_EXEC_CONT vtkm::Sphere make_SphereFrom4Points(const vtkm::Vec& a0, + const vtkm::Vec& a1, + const vtkm::Vec& a2, + const vtkm::Vec& a3, + CoordType tol) { // Choose p3 such that the min(p3 - p[012]) is larger than any other choice of p3. // From: http://steve.hollasch.net/cgindex/geometry/sphere4pts.html, From 1365cfa9ecef54ac20c0b8bc43331f5aff1df558 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 16 Sep 2020 14:18:54 -0400 Subject: [PATCH 48/51] Update ConnectivityExtrude to follow clangs rules on markup --- vtkm/exec/ConnectivityExtrude.h | 19 ++++++++++--------- vtkm/exec/arg/ThreadIndicesExtrude.h | 2 ++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/vtkm/exec/ConnectivityExtrude.h b/vtkm/exec/ConnectivityExtrude.h index 0910c63a4..527618cd4 100644 --- a/vtkm/exec/ConnectivityExtrude.h +++ b/vtkm/exec/ConnectivityExtrude.h @@ -194,7 +194,7 @@ ConnectivityExtrude::ConnectivityExtrude(const ConnectivityPortalType& c } template -typename ConnectivityExtrude::IndicesType ConnectivityExtrude::GetIndices( +VTKM_EXEC typename ConnectivityExtrude::IndicesType ConnectivityExtrude::GetIndices( const vtkm::Id2& index) const { vtkm::Id tr = index[0]; @@ -217,13 +217,14 @@ typename ConnectivityExtrude::IndicesType ConnectivityExtrude::G template -ReverseConnectivityExtrude::ReverseConnectivityExtrude(const ConnectivityPortalType& conn, - const OffsetsPortalType& offsets, - const CountsPortalType& counts, - const PrevNodePortalType& prevNode, - vtkm::Int32 cellsPerPlane, - vtkm::Int32 pointsPerPlane, - vtkm::Int32 numPlanes) +VTKM_EXEC ReverseConnectivityExtrude::ReverseConnectivityExtrude( + const ConnectivityPortalType& conn, + const OffsetsPortalType& offsets, + const CountsPortalType& counts, + const PrevNodePortalType& prevNode, + vtkm::Int32 cellsPerPlane, + vtkm::Int32 pointsPerPlane, + vtkm::Int32 numPlanes) : Connectivity(conn) , Offsets(offsets) , Counts(counts) @@ -235,7 +236,7 @@ ReverseConnectivityExtrude::ReverseConnectivityExtrude(const Connectivit } template -typename ReverseConnectivityExtrude::IndicesType +VTKM_EXEC typename ReverseConnectivityExtrude::IndicesType ReverseConnectivityExtrude::GetIndices(const vtkm::Id2& index) const { auto ptCur = index[0]; diff --git a/vtkm/exec/arg/ThreadIndicesExtrude.h b/vtkm/exec/arg/ThreadIndicesExtrude.h index feaf5835a..6319702d5 100644 --- a/vtkm/exec/arg/ThreadIndicesExtrude.h +++ b/vtkm/exec/arg/ThreadIndicesExtrude.h @@ -214,6 +214,7 @@ public: this->IndicesIncident = connectivity.GetIndices(logicalIndex); } + VTKM_EXEC ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex3D, vtkm::Id threadIndex1D, const ConnectivityType& connectivity) @@ -229,6 +230,7 @@ public: this->IndicesIncident = connectivity.GetIndices(logicalIndex); } + VTKM_EXEC ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex3D, vtkm::Id threadIndex1D, vtkm::Id inputIndex, From d0c9fb2741f54e3910f2b076a8d0cd1b9f276b55 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 22 Sep 2020 13:19:41 -0400 Subject: [PATCH 49/51] Correct missing `VTKM_EXEC_CONT` in UnitTestArrayHandleExtrude --- vtkm/cont/testing/UnitTestArrayHandleExtrude.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/cont/testing/UnitTestArrayHandleExtrude.cxx b/vtkm/cont/testing/UnitTestArrayHandleExtrude.cxx index a4a97fc41..939d43cf8 100644 --- a/vtkm/cont/testing/UnitTestArrayHandleExtrude.cxx +++ b/vtkm/cont/testing/UnitTestArrayHandleExtrude.cxx @@ -66,7 +66,7 @@ struct CopyValue : public vtkm::worklet::WorkletMapField typedef _2 ExecutionSignature(_1); template - T&& operator()(T&& t) const + VTKM_EXEC_CONT T&& operator()(T&& t) const { return std::forward(t); } From 68b5edfcba151291f16c653b67ef689ce77a68dd Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 25 Sep 2020 11:06:34 -0400 Subject: [PATCH 50/51] VTK-m defines VTKM_EXEC / VTKM_EXEC_CONT when compiling with HIP --- vtkm/internal/Configure.h.in | 5 +++++ vtkm/internal/ExportMacros.h | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/vtkm/internal/Configure.h.in b/vtkm/internal/Configure.h.in index dc37a7d7d..79b7af339 100644 --- a/vtkm/internal/Configure.h.in +++ b/vtkm/internal/Configure.h.in @@ -20,6 +20,11 @@ #define VTKM_CUDA_DEVICE_PASS #endif +// Defined when compiling for the HIP language. +#ifdef __HIP__ +#define VTKM_HIP +#endif + #if defined(_MSC_VER) //MSVC 2015+ can use a clang frontend, so we want to label it only as MSVC //and not MSVC and clang diff --git a/vtkm/internal/ExportMacros.h b/vtkm/internal/ExportMacros.h index b12bef2e7..7a5e55776 100644 --- a/vtkm/internal/ExportMacros.h +++ b/vtkm/internal/ExportMacros.h @@ -16,7 +16,14 @@ * Export macros for various parts of the VTKm library. */ -#ifdef VTKM_CUDA +#ifdef VTKM_HIP + +#include "hip/hip_runtime.h" +#define VTKM_EXEC __device__ __host__ +#define VTKM_EXEC_CONT __device__ __host__ +#define VTKM_SUPPRESS_EXEC_WARNINGS + +#elif defined(VTKM_CUDA) #define VTKM_EXEC __device__ __host__ #define VTKM_EXEC_CONT __device__ __host__ From 9bd6f3e6da2b7cc1eb08afd7122f4857baba0d41 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 16 Sep 2020 10:04:12 -0400 Subject: [PATCH 51/51] Disable VTKM_ASSERT when using HIP --- CMakeLists.txt | 6 ++++++ docs/changelog/hip-no-assert.md | 12 ++++++++++++ vtkm/Assert.h | 2 ++ vtkm/internal/CMakeLists.txt | 1 + vtkm/internal/Configure.h.in | 4 ++++ 5 files changed, 25 insertions(+) create mode 100644 docs/changelog/hip-no-assert.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b12223d8..bab37198f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,12 @@ vtkm_option(VTKm_NO_ASSERT "Disable assertions in debugging builds." OFF) # for CUDA devices. vtkm_option(VTKm_NO_ASSERT_CUDA "Disable assertions for CUDA devices." ON) +# The HIP compiler (as of ROCm 3.7) takes a surprising long time to compile +# kernels with assert in them they generate `printf` calls which are very +# slow ( cause massive register spillage). By default we turn off asserts when +# compiling for HIP devices. +vtkm_option(VTKm_NO_ASSERT_HIP "Disable assertions for HIP devices." ON) + # When VTK-m is embedded into larger projects that wish to make end user # applications they want to only install libraries and don't want CMake/headers # installed. diff --git a/docs/changelog/hip-no-assert.md b/docs/changelog/hip-no-assert.md new file mode 100644 index 000000000..ff448b0f1 --- /dev/null +++ b/docs/changelog/hip-no-assert.md @@ -0,0 +1,12 @@ +# Disable asserts for HIP architecture builds + +`assert` is supported on recent HIP cards, but compiling it is very slow, +as it triggers the usage of `printf` which. Currently (ROCm 3.7) `printf` +has a severe performance penalty and should be avoided when possible. +By default, the `VTKM_ASSERT` macro has been disabled whenever compiling +for a HIP device via kokkos. + +Asserts for HIP devices can be turned back on by turning the +`VTKm_NO_ASSERT_HIP` CMake variable off. Turning this CMake variable off +will enable assertions in HIP kernels unless there is another reason +turning off all asserts (such as a release build). diff --git a/vtkm/Assert.h b/vtkm/Assert.h index 646ef5ec1..f26c1e322 100644 --- a/vtkm/Assert.h +++ b/vtkm/Assert.h @@ -21,6 +21,8 @@ #define VTKM_NO_ASSERT #elif defined(VTKM_CUDA_DEVICE_PASS) && defined(VTKM_NO_ASSERT_CUDA) #define VTKM_NO_ASSERT +#elif defined(VTKM_HIP) && defined(VTKM_NO_ASSERT_HIP) +#define VTKM_NO_ASSERT #endif #endif // VTKM_NO_ASSERT diff --git a/vtkm/internal/CMakeLists.txt b/vtkm/internal/CMakeLists.txt index 4224aaa2c..b40fa2c17 100755 --- a/vtkm/internal/CMakeLists.txt +++ b/vtkm/internal/CMakeLists.txt @@ -15,6 +15,7 @@ set(VTKM_NO_ASSERT ${VTKm_NO_ASSERT}) set(VTKM_NO_ASSERT_CUDA ${VTKm_NO_ASSERT_CUDA}) +set(VTKM_NO_ASSERT_HIP ${VTKm_NO_ASSERT_HIP}) set(VTKM_USE_DOUBLE_PRECISION ${VTKm_USE_DOUBLE_PRECISION}) set(VTKM_USE_64BIT_IDS ${VTKm_USE_64BIT_IDS}) diff --git a/vtkm/internal/Configure.h.in b/vtkm/internal/Configure.h.in index 79b7af339..06dd2b676 100644 --- a/vtkm/internal/Configure.h.in +++ b/vtkm/internal/Configure.h.in @@ -71,6 +71,10 @@ #cmakedefine VTKM_NO_ASSERT_CUDA #endif +#if !defined(VTKM_NO_ASSERT_HIP) +#cmakedefine VTKM_NO_ASSERT_HIP +#endif + #if !defined(VTKM_USE_DOUBLE_PRECISION) && !defined(VTKM_NO_DOUBLE_PRECISION) #cmakedefine VTKM_USE_DOUBLE_PRECISION #endif