diff --git a/.gitlab/ci/config/google_benchmarks.sh b/.gitlab/ci/config/google_benchmarks.sh index 9866ed4c7..5e8aef597 100755 --- a/.gitlab/ci/config/google_benchmarks.sh +++ b/.gitlab/ci/config/google_benchmarks.sh @@ -2,10 +2,10 @@ set -xe -readonly version="91ed7eea6856f8785139c58fbcc827e82579243c" +readonly version="v1.6.1" readonly tarball="$version.tar.gz" readonly url="https://github.com/google/benchmark/archive/$tarball" -readonly sha256sum="039054b7919b0af1082b121df35f4c24fccdd97f308e3dc28f36a0d3a3c64c69" +readonly sha256sum="6132883bc8c9b0df5375b16ab520fac1a85dc9e4cf5be59480448ece74b278d4" readonly install_dir="$HOME/gbench" if ! [[ "$VTKM_SETTINGS" =~ "benchmarks" ]]; then diff --git a/CMake/VTKmDeviceAdapters.cmake b/CMake/VTKmDeviceAdapters.cmake index 006448e72..15895313e 100644 --- a/CMake/VTKmDeviceAdapters.cmake +++ b/CMake/VTKmDeviceAdapters.cmake @@ -324,6 +324,7 @@ if(VTKm_ENABLE_KOKKOS AND NOT TARGET vtkm::kokkos) cmake_minimum_required(VERSION 3.18 FATAL_ERROR) enable_language(HIP) add_library(vtkm::kokkos_hip INTERFACE IMPORTED GLOBAL) + set_property(TARGET Kokkos::kokkoscore PROPERTY INTERFACE_COMPILE_DEFINITIONS "") set_property(TARGET Kokkos::kokkoscore PROPERTY INTERFACE_COMPILE_OPTIONS "") set_property(TARGET Kokkos::kokkoscore PROPERTY INTERFACE_LINK_OPTIONS "") endif() diff --git a/benchmarking/BenchmarkFilters.cxx b/benchmarking/BenchmarkFilters.cxx index 8c5a7fc7f..12d89fe34 100644 --- a/benchmarking/BenchmarkFilters.cxx +++ b/benchmarking/BenchmarkFilters.cxx @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -41,6 +40,7 @@ #include #include #include +#include #include #include @@ -193,7 +193,7 @@ void BenchThreshold(::benchmark::State& state) vtkm::Float64 quarter = range.Length() / 4.; vtkm::Float64 mid = range.Center(); - vtkm::filter::Threshold filter; + vtkm::filter::entity_extraction::Threshold filter; filter.SetActiveField(PointScalarsName, vtkm::cont::Field::Association::POINTS); filter.SetLowerThreshold(mid - quarter); filter.SetUpperThreshold(mid + quarter); diff --git a/docs/changelog/arraycopy-precompiled.md b/docs/changelog/arraycopy-precompiled.md new file mode 100644 index 000000000..42bf9e5c4 --- /dev/null +++ b/docs/changelog/arraycopy-precompiled.md @@ -0,0 +1,11 @@ +# Make ArrayCopy not depend on a device compiler + +Rather than require `ArrayCopy` to create special versions of copy for +all arrays, use a precompiled versions. This should speed up compiles, +reduce the amount of code being generated, and require the device +compiler on fewer source files. + +There are some cases where you still need to copy arrays that are not +well supported by the precompiled versions in `ArrayCopy`. (It will +always work, but the fallback is very slow.) In this case, you will want +to switch over to `ArrayCopyDevice`, which has the old behavior. diff --git a/examples/histogram/HistogramMPI.hxx b/examples/histogram/HistogramMPI.hxx index c94a58ae1..013d9a626 100644 --- a/examples/histogram/HistogramMPI.hxx +++ b/examples/histogram/HistogramMPI.hxx @@ -8,7 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include diff --git a/vtkm/cont/ArrayCopy.cxx b/vtkm/cont/ArrayCopy.cxx index a3637f568..1ae0dcd9a 100644 --- a/vtkm/cont/ArrayCopy.cxx +++ b/vtkm/cont/ArrayCopy.cxx @@ -9,178 +9,43 @@ //============================================================================ #include -#include -#include - -#include - -#include - -namespace -{ - -// Use a worklet because device adapter copies often have an issue with casting the values from the -// `ArrayHandleRecomineVec` that comes from `UnknownArrayHandle::CastAndCallWithExtractedArray`. -struct CopyWorklet : vtkm::worklet::WorkletMapField -{ - using ControlSignature = void(FieldIn, FieldOut); - using ExecutionSignature = void(_1, _2); - using InputDomain = _1; - - template - VTKM_EXEC void operator()(const InType& in, OutType& out) const - { - out = in; - } -}; - -struct UnknownCopyOnDevice -{ - bool Called = false; - - template - void operator()(vtkm::cont::DeviceAdapterId device, - const vtkm::cont::ArrayHandleRecombineVec& in, - const vtkm::cont::ArrayHandleRecombineVec& out) - { - // Note: ArrayHandleRecombineVec returns the wrong value for IsOnDevice (always true). - // This is one of the consequences of ArrayHandleRecombineVec breaking assumptions of - // ArrayHandle. It does this by stuffing Buffer objects in another Buffer's meta data - // rather than listing them explicitly (where they can be queried). We get around this - // by pulling out one of the component arrays and querying that. - if (!this->Called && - ((device == vtkm::cont::DeviceAdapterTagAny{}) || - (in.GetComponentArray(0).IsOnDevice(device)))) - { - vtkm::cont::Invoker invoke(device); - invoke(CopyWorklet{}, in, out); - this->Called = true; - } - } -}; - -struct UnknownCopyFunctor2 -{ - template - void operator()(const vtkm::cont::ArrayHandleRecombineVec& out, - const vtkm::cont::ArrayHandleRecombineVec& in) const - { - UnknownCopyOnDevice doCopy; - - // Try to copy on a device that the data are already on. - vtkm::ListForEach(doCopy, VTKM_DEFAULT_DEVICE_ADAPTER_LIST{}, in, out); - - // If it was not on any device, call one more time with any adapter to copy wherever. - doCopy(vtkm::cont::DeviceAdapterTagAny{}, in, out); - } -}; - -struct UnknownCopyFunctor1 -{ - template - void operator()(const vtkm::cont::ArrayHandleRecombineVec& in, - const vtkm::cont::UnknownArrayHandle& out) const - { - out.Allocate(in.GetNumberOfValues()); - - this->DoIt(in, out, typename std::is_same::type{}); - } - - template - void DoIt(const vtkm::cont::ArrayHandleRecombineVec& in, - const vtkm::cont::UnknownArrayHandle& out, - std::false_type) const - { - // Source is not float. - if (out.IsBaseComponentType()) - { - // Arrays have the same base component type. Copy directly. - UnknownCopyFunctor2{}(out.ExtractArrayFromComponents(), in); - } - else if (out.IsBaseComponentType()) - { - // Can copy anything to default float. - UnknownCopyFunctor2{}(out.ExtractArrayFromComponents(), in); - } - else - { - // Arrays have different base types. To reduce the number of template paths from nxn to 3n, - // copy first to a temp array of default float. - vtkm::cont::UnknownArrayHandle temp = out.NewInstanceFloatBasic(); - (*this)(in, temp); - vtkm::cont::ArrayCopy(temp, out); - } - } - - template - void DoIt(const vtkm::cont::ArrayHandleRecombineVec& in, - const vtkm::cont::UnknownArrayHandle& out, - std::true_type) const - { - // Source array is FloatDefault. That should be copiable to anything. - out.CastAndCallWithExtractedArray(UnknownCopyFunctor2{}, in); - } -}; - -void DoUnknownArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - const vtkm::cont::UnknownArrayHandle& destination) -{ - if (source.GetNumberOfValues() > 0) - { - source.CastAndCallWithExtractedArray(UnknownCopyFunctor1{}, destination); - } - else - { - destination.ReleaseResources(); - } -} - -} // anonymous namespace +#include namespace vtkm { namespace cont { - -void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - vtkm::cont::UnknownArrayHandle& destination) +namespace detail { - if (!destination.IsValid()) + +void ArrayCopyConcreteSrc::CopyCountingFloat( + vtkm::FloatDefault start, + vtkm::FloatDefault step, + vtkm::Id size, + const vtkm::cont::UnknownArrayHandle& result) const +{ + if (result.IsBaseComponentType()) { - destination = source.NewInstanceBasic(); + auto outArray = result.ExtractComponent(0); + vtkm::cont::ArrayCopyDevice(vtkm::cont::make_ArrayHandleCounting(start, step, size), outArray); } - - DoUnknownArrayCopy(source, destination); -} - -void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - const vtkm::cont::UnknownArrayHandle& destination) -{ - if (!destination.IsValid()) + else { - throw vtkm::cont::ErrorBadValue( - "Attempty to copy to a constant UnknownArrayHandle with no valid array."); + vtkm::cont::ArrayHandle outArray; + outArray.Allocate(size); + CopyCountingFloat(start, step, size, outArray); + result.DeepCopyFrom(outArray); } - - DoUnknownArrayCopy(source, destination); } -namespace internal +vtkm::cont::ArrayHandle ArrayCopyConcreteSrc::CopyCountingId( + const vtkm::cont::ArrayHandleCounting& source) const { - -void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source, - vtkm::cont::UnknownArrayHandle& destination) -{ - vtkm::cont::ArrayCopy(source, destination); + vtkm::cont::ArrayHandle destination; + vtkm::cont::ArrayCopyDevice(source, destination); + return destination; } -void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source, - const vtkm::cont::UnknownArrayHandle& destination) -{ - vtkm::cont::ArrayCopy(source, destination); } - -} // namespace vtkm::cont::internal - -} // namespace vtkm::cont -} // namespace vtkm +} +} // namespace vtkm::cont::detail diff --git a/vtkm/cont/ArrayCopy.h b/vtkm/cont/ArrayCopy.h index f72d8b01a..612a7e4f4 100644 --- a/vtkm/cont/ArrayCopy.h +++ b/vtkm/cont/ArrayCopy.h @@ -10,19 +10,20 @@ #ifndef vtk_m_cont_ArrayCopy_h #define vtk_m_cont_ArrayCopy_h -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include -#include - #include -// TODO: When virtual arrays are available, compile the implementation in a .cxx/.cu file. Common -// arrays are copied directly but anything else would be copied through virtual methods. +#include + +#include +#include namespace vtkm { @@ -32,72 +33,91 @@ namespace cont namespace detail { -// Element-wise copy. -template -void ArrayCopyWithAlgorithm(const InArrayType& source, OutArrayType& destination) +// Compile-time check to make sure that an `ArrayHandle` passed to `ArrayCopy` +// can be passed to a `UnknownArrayHandle`. This function does nothing +// except provide a compile error that is easier to understand than if you +// let it go and error in `UnknownArrayHandle`. (Huh? I'm not using that.) +template +inline void ArrayCopyValueTypeCheck() { - // Current implementation of Algorithm::Copy will first try to copy on devices where the - // data is already available. - vtkm::cont::Algorithm::Copy(source, destination); + VTKM_STATIC_ASSERT_MSG(vtkm::HasVecTraits::value, + "An `ArrayHandle` that has a special value type that is not supported " + "by the precompiled version of `ArrayCopy` has been used. If this array " + "must be deep copied, consider using `ArrayCopyDevice`. Look at the " + "compile error for the type assigned to template parameter `T` to " + "see the offending type."); } -// TODO: Remove last argument once ArryHandleNewStyle becomes ArrayHandle -template -void ArrayCopyOldImpl(const InArrayType& in, OutArrayType& out, std::false_type /* Copy storage */) -{ - ArrayCopyWithAlgorithm(in, out); -} +template +struct ArrayCopyConcreteSrc; -// Copy storage for implicit arrays, must be of same type: -// TODO: This will go away once ArrayHandleNewStyle becomes ArrayHandle. -template -void ArrayCopyOldImpl(const ArrayType& in, ArrayType& out, std::true_type /* Copy storage */) +template +inline void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source, + vtkm::cont::UnknownArrayHandle& destination, + SrcIsArrayHandle, + std::false_type) { - // This is only called if in/out are the same type and the handle is not - // writable. This allows read-only implicit array handles to be copied. - auto newStorage = in.GetStorage(); - out = ArrayType(newStorage); + destination.DeepCopyFrom(source); } - -// TODO: This will go away once ArrayHandleNewStyle becomes ArrayHandle. -template -VTKM_CONT void ArrayCopyImpl(const InArrayType& source, - OutArrayType& destination, - std::false_type /* New style */) -{ - using SameTypes = std::is_same; - using IsWritable = vtkm::cont::internal::IsWritableArrayHandle; - using JustCopyStorage = std::integral_constant; - ArrayCopyOldImpl(source, destination, JustCopyStorage{}); -} - -// TODO: ArrayHandleNewStyle will eventually become ArrayHandle, in which case this -// will become ArrayCopyWithAlgorithm -template -VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, - vtkm::cont::ArrayHandle& destination, - std::true_type /* New style */) -{ - VTKM_STATIC_ASSERT((!std::is_same::value || !std::is_same::value)); - ArrayCopyWithAlgorithm(source, destination); -} - -// TODO: ArrayHandleNewStyle will eventually become ArrayHandle, in which case this -// will become the only version with the same array types. -template -VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, - vtkm::cont::ArrayHandle& destination, - std::true_type /* New style */) +template +inline void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source, + const vtkm::cont::UnknownArrayHandle& destination, + SrcIsArrayHandle, + std::false_type) { destination.DeepCopyFrom(source); } -} // namespace detail +template +void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source, + vtkm::cont::ArrayHandle& destination, + std::false_type, + std::true_type) +{ + detail::ArrayCopyValueTypeCheck(); + + using DestType = vtkm::cont::ArrayHandle; + if (source.CanConvert()) + { + destination.DeepCopyFrom(source.AsArrayHandle()); + } + else + { + vtkm::cont::UnknownArrayHandle destWrapper(destination); + vtkm::cont::detail::ArrayCopyImpl(source, destWrapper, std::false_type{}, std::false_type{}); + // Destination array should not change, but just in case. + destWrapper.AsArrayHandle(destination); + } +} + +template +void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination, + std::true_type, + std::true_type) +{ + ArrayCopyValueTypeCheck(); + ArrayCopyValueTypeCheck(); + + detail::ArrayCopyConcreteSrc{}(source, destination); +} + +// Special case of copying data when type is the same. +template +void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination, + std::true_type, + std::true_type) +{ + destination.DeepCopyFrom(source); +} + +} /// \brief Does a deep copy from one array to another array. /// -/// Given a source \c ArrayHandle and a destination \c ArrayHandle, this -/// function allocates the destination \c ArrayHandle to the correct size and +/// Given a source `ArrayHandle` and a destination `ArrayHandle`, this +/// function allocates the destination `ArrayHandle` to the correct size and /// deeply copies all the values from the source to the destination. /// /// This method will attempt to copy the data using the device that the input @@ -108,61 +128,41 @@ VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, /// This should work on some non-writable array handles as well, as long as /// both \a source and \a destination are the same type. /// +/// This version of array copy uses a precompiled version of copy that is +/// efficient for most standard memory layouts. However, there are some +/// types of fancy `ArrayHandle` that cannot be handled directly, and +/// the fallback for these arrays can be slow. If you see a warning in +/// the log about an inefficient memory copy when extracting a component, +/// pay heed and look for a different way to copy the data (perhaps +/// using `ArrayCopyDevice`). +/// /// @{ /// -template -VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle& source, - vtkm::cont::ArrayHandle& destination) +template +inline void ArrayCopy(const SourceArrayType& source, DestArrayType& destination) { - using InArrayType = vtkm::cont::ArrayHandle; - using OutArrayType = vtkm::cont::ArrayHandle; - using SameTypes = std::is_same; - using IsWritable = vtkm::cont::internal::IsWritableArrayHandle; - - // There are three cases handled here: - // 1. The arrays are the same type: - // -> Deep copy the buffers and the Storage object - // 2. The arrays are different and the output is writable: - // -> Do element-wise copy - // 3. The arrays are different and the output is not writable: - // -> fail (cannot copy) - - // Give a nice error message for case 3: - VTKM_STATIC_ASSERT_MSG(IsWritable::value || SameTypes::value, - "Cannot copy to a read-only array with a different " - "type than the source."); - - using IsOldStyle = - std::is_base_of, - InArrayType>; - - // Static dispatch cases 1 & 2 - detail::ArrayCopyImpl(source, destination, std::integral_constant{}); + detail::ArrayCopyImpl(source, + destination, + typename internal::ArrayHandleCheck::type{}, + typename internal::ArrayHandleCheck::type{}); } - -VTKM_CONT_EXPORT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - vtkm::cont::UnknownArrayHandle& destination); - -VTKM_CONT_EXPORT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - const vtkm::cont::UnknownArrayHandle& destination); - -template -VTKM_CONT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - vtkm::cont::ArrayHandle& destination) +// Special case where we allow a const UnknownArrayHandle as output. +template +inline void ArrayCopy(const SourceArrayType& source, vtkm::cont::UnknownArrayHandle& destination) { - using DestType = vtkm::cont::ArrayHandle; - if (source.CanConvert()) - { - ArrayCopy(source.AsArrayHandle(), destination); - } - else - { - vtkm::cont::UnknownArrayHandle destWrapper(destination); - ArrayCopy(source, destWrapper); - // Destination array should not change, but just in case. - destWrapper.AsArrayHandle(destination); - } + detail::ArrayCopyImpl(source, + destination, + typename internal::ArrayHandleCheck::type{}, + std::false_type{}); +} + +// Invalid const ArrayHandle in destination, which is not allowed because it will +// not work in all cases. +template +void ArrayCopy(const vtkm::cont::UnknownArrayHandle&, const vtkm::cont::ArrayHandle&) +{ + VTKM_STATIC_ASSERT_MSG(sizeof(T) == 0, "Copying to a constant ArrayHandle is not allowed."); } /// @} @@ -190,13 +190,160 @@ VTKM_CONT void ArrayCopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle s else { vtkm::cont::UnknownArrayHandle destWrapper(destination); - ArrayCopy(source, destWrapper); + vtkm::cont::ArrayCopy(source, destWrapper); // Destination array should not change, but just in case. destWrapper.AsArrayHandle(destination); } } -} -} // namespace vtkm::cont +namespace detail +{ + +template +struct ArrayCopyConcreteSrc +{ + template + void operator()(const vtkm::cont::ArrayHandle& source, DestArray& destination) const + { + using ArrayType = vtkm::cont::ArrayHandle; + this->DoIt( + source, destination, vtkm::cont::internal::ArrayExtractComponentIsInefficient{}); + } + + template + void DoIt(const vtkm::cont::ArrayHandle& source, + DestArray& destination, + std::false_type vtkmNotUsed(isInefficient)) const + { + vtkm::cont::ArrayCopy(vtkm::cont::UnknownArrayHandle{ source }, destination); + } + + template + void DoIt(const vtkm::cont::ArrayHandle& source, + DestArray& destination, + std::true_type vtkmNotUsed(isInefficient)) const + { + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Attempting to copy from an array of type " + + vtkm::cont::TypeToString>() + + " with ArrayCopy is inefficient. It is highly recommended you use another method " + "such as vtkm::cont::ArrayCopyDevice."); + // Still call the precompiled `ArrayCopy`. You will get another warning after this, + // but it will still technically work, albiet slowly. + vtkm::cont::ArrayCopy(vtkm::cont::UnknownArrayHandle{ source }, destination); + } +}; + +// Special case for constant arrays to be efficient. +template <> +struct ArrayCopyConcreteSrc +{ + template + void operator()(const vtkm::cont::ArrayHandle& source_, + vtkm::cont::ArrayHandle& destination) const + { + vtkm::cont::ArrayHandleConstant source = source_; + destination.AllocateAndFill(source.GetNumberOfValues(), static_cast(source.GetValue())); + } +}; + +// Special case for ArrayHandleIndex to be efficient. +template <> +struct ArrayCopyConcreteSrc +{ + template + void operator()(const vtkm::cont::ArrayHandleIndex& source, + vtkm::cont::ArrayHandle& destination) const + { + // Skip warning about inefficient copy because there is a special case in ArrayCopyUnknown.cxx + // to copy ArrayHandleIndex efficiently. + vtkm::cont::ArrayCopy(vtkm::cont::UnknownArrayHandle{ source }, destination); + } +}; + +// Special case for ArrayHandleCounting to be efficient. +template <> +struct VTKM_CONT_EXPORT ArrayCopyConcreteSrc +{ + template + void operator()(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination) const + { + vtkm::cont::ArrayHandleCounting countingSource = source; + T1 start = countingSource.GetStart(); + T1 step = countingSource.GetStep(); + vtkm::Id size = countingSource.GetNumberOfValues(); + destination.Allocate(size); + vtkm::cont::UnknownArrayHandle unknownDest = destination; + + using VTraits1 = vtkm::VecTraits; + using VTraits2 = vtkm::VecTraits; + for (vtkm::IdComponent comp = 0; comp < VTraits1::GetNumberOfComponents(start); ++comp) + { + this->CopyCountingFloat( + static_cast(VTraits1::GetComponent(start, comp)), + static_cast(VTraits1::GetComponent(step, comp)), + size, + unknownDest.ExtractComponent(comp)); + } + } + + void operator()(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination) const + { + destination = this->CopyCountingId(source); + } + +private: + void CopyCountingFloat(vtkm::FloatDefault start, + vtkm::FloatDefault step, + vtkm::Id size, + const vtkm::cont::UnknownArrayHandle& result) const; + vtkm::cont::ArrayHandle CopyCountingId( + const vtkm::cont::ArrayHandleCounting& source) const; +}; + +// Special case for ArrayHandleConcatenate to be efficient +template +struct ArrayCopyConcreteSrc> +{ + template + void operator()(const SourceArrayType& source, DestArrayType& destination) const + { + auto source1 = source.GetStorage().GetArray1(source.GetBuffers()); + auto source2 = source.GetStorage().GetArray2(source.GetBuffers()); + + // Need to preallocate because view decorator will not be able to resize. + destination.Allocate(source.GetNumberOfValues()); + auto dest1 = vtkm::cont::make_ArrayHandleView(destination, 0, source1.GetNumberOfValues()); + auto dest2 = vtkm::cont::make_ArrayHandleView( + destination, source1.GetNumberOfValues(), source2.GetNumberOfValues()); + + vtkm::cont::ArrayCopy(source1, dest1); + vtkm::cont::ArrayCopy(source2, dest2); + } +}; + +// Special case for ArrayHandlePermutation to be efficient +template +struct ArrayCopyConcreteSrc> +{ + using SourceStorageTag = vtkm::cont::StorageTagPermutation; + template + void operator()(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination) const + { + auto indexArray = source.GetStorage().GetIndexArray(source.GetBuffers()); + auto valueArray = source.GetStorage().GetValueArray(source.GetBuffers()); + vtkm::cont::UnknownArrayHandle copy = + vtkm::cont::internal::MapArrayPermutation(valueArray, indexArray); + vtkm::cont::ArrayCopyShallowIfPossible(copy, destination); + } +}; + +} // namespace detail + +} // namespace cont +} // namespace vtkm #endif //vtk_m_cont_ArrayCopy_h diff --git a/vtkm/cont/ArrayCopyDevice.h b/vtkm/cont/ArrayCopyDevice.h new file mode 100644 index 000000000..fcd94a7ac --- /dev/null +++ b/vtkm/cont/ArrayCopyDevice.h @@ -0,0 +1,153 @@ +//============================================================================ +// 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_ArrayCopyDevice_h +#define vtk_m_cont_ArrayCopyDevice_h + +#include +#include +#include +#include +#include +#include + +#include + +#include + +// TODO: When virtual arrays are available, compile the implementation in a .cxx/.cu file. Common +// arrays are copied directly but anything else would be copied through virtual methods. + +namespace vtkm +{ +namespace cont +{ + +namespace detail +{ + +// Element-wise copy. +template +void ArrayCopyWithAlgorithm(const InArrayType& source, OutArrayType& destination) +{ + // Current implementation of Algorithm::Copy will first try to copy on devices where the + // data is already available. + vtkm::cont::Algorithm::Copy(source, destination); +} + +// TODO: Remove last argument once ArryHandleNewStyle becomes ArrayHandle +template +void ArrayCopyOldImpl(const InArrayType& in, OutArrayType& out, std::false_type /* Copy storage */) +{ + ArrayCopyWithAlgorithm(in, out); +} + +// Copy storage for implicit arrays, must be of same type: +// TODO: This will go away once ArrayHandleNewStyle becomes ArrayHandle. +template +void ArrayCopyOldImpl(const ArrayType& in, ArrayType& out, std::true_type /* Copy storage */) +{ + // This is only called if in/out are the same type and the handle is not + // writable. This allows read-only implicit array handles to be copied. + auto newStorage = in.GetStorage(); + out = ArrayType(newStorage); +} + +// TODO: This will go away once ArrayHandleNewStyle becomes ArrayHandle. +template +VTKM_CONT void ArrayCopyImpl(const InArrayType& source, + OutArrayType& destination, + std::false_type /* New style */) +{ + using SameTypes = std::is_same; + using IsWritable = vtkm::cont::internal::IsWritableArrayHandle; + using JustCopyStorage = std::integral_constant; + ArrayCopyOldImpl(source, destination, JustCopyStorage{}); +} + +// TODO: ArrayHandleNewStyle will eventually become ArrayHandle, in which case this +// will become ArrayCopyWithAlgorithm +template +VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination, + std::true_type /* New style */) +{ + VTKM_STATIC_ASSERT((!std::is_same::value || !std::is_same::value)); + ArrayCopyWithAlgorithm(source, destination); +} + +// TODO: ArrayHandleNewStyle will eventually become ArrayHandle, in which case this +// will become the only version with the same array types. +template +VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination, + std::true_type /* New style */) +{ + destination.DeepCopyFrom(source); +} + +} // namespace detail + +/// \brief Does a deep copy from one array to another array. +/// +/// Given a source `ArrayHandle` and a destination `ArrayHandle`, this +/// function allocates the destination `ArrayHandle` to the correct size and +/// deeply copies all the values from the source to the destination. +/// +/// This method will attempt to copy the data using the device that the input +/// data is already valid on. If the input data is only valid in the control +/// environment, the runtime device tracker is used to try to find another +/// device. +/// +/// This should work on some non-writable array handles as well, as long as +/// both \a source and \a destination are the same type. +/// +/// This version of array copy is templated to create custom code for the +/// particular types of `ArrayHandle`s that you are copying. This will +/// ensure that you get the best possible copy, but requires a device +/// compiler and tends to bloat the code. +/// +/// @{ +/// +template +VTKM_CONT void ArrayCopyDevice(const vtkm::cont::ArrayHandle& source, + vtkm::cont::ArrayHandle& destination) +{ + using InArrayType = vtkm::cont::ArrayHandle; + using OutArrayType = vtkm::cont::ArrayHandle; + using SameTypes = std::is_same; + using IsWritable = vtkm::cont::internal::IsWritableArrayHandle; + + // There are three cases handled here: + // 1. The arrays are the same type: + // -> Deep copy the buffers and the Storage object + // 2. The arrays are different and the output is writable: + // -> Do element-wise copy + // 3. The arrays are different and the output is not writable: + // -> fail (cannot copy) + + // Give a nice error message for case 3: + VTKM_STATIC_ASSERT_MSG(IsWritable::value || SameTypes::value, + "Cannot copy to a read-only array with a different " + "type than the source."); + + using IsOldStyle = + std::is_base_of, + InArrayType>; + + // Static dispatch cases 1 & 2 + detail::ArrayCopyImpl(source, destination, std::integral_constant{}); +} + +/// @} + +} +} // namespace vtkm::cont + +#endif //vtk_m_cont_ArrayCopyDevice_h diff --git a/vtkm/cont/ArrayExtractComponent.h b/vtkm/cont/ArrayExtractComponent.h index 238236ec2..96592af23 100644 --- a/vtkm/cont/ArrayExtractComponent.h +++ b/vtkm/cont/ArrayExtractComponent.h @@ -19,6 +19,8 @@ #include #include +#include + #include namespace vtkm @@ -137,6 +139,39 @@ struct ArrayExtractComponentImpl } }; +namespace detail +{ + +template +struct ForwardSuper : Super +{ +}; + +template +struct SharedSupersImpl; + +template +struct SharedSupersImpl, Supers...> + : ForwardSuper... +{ +}; + +} // namespace detail + +// `ArrayExtractComponentImpl`s that modify the behavior from other storage types might +// want to inherit from the `ArrayExtractComponentImpl`s of these storage types. However, +// if the template specifies multiple storage types, two of the same might be specified, +// and it is illegal in C++ to directly inherit from the same type twice. This special +// superclass accepts a variable amout of superclasses. Inheriting from this will inherit +// from all these superclasses, and duplicates are allowed. +template +using DuplicatedSuperclasses = + detail::SharedSupersImpl, Supers...>; + +template +using ArrayExtractComponentImplInherit = + DuplicatedSuperclasses...>; + /// \brief Resolves to true if ArrayHandleComponent of the array handle would be inefficient. /// template diff --git a/vtkm/cont/ArrayHandleCartesianProduct.h b/vtkm/cont/ArrayHandleCartesianProduct.h index 79b8aaf49..8693b8c3e 100644 --- a/vtkm/cont/ArrayHandleCartesianProduct.h +++ b/vtkm/cont/ArrayHandleCartesianProduct.h @@ -379,8 +379,11 @@ VTKM_CONT namespace internal { +// Superclass will inherit the ArrayExtractComponentImplInefficient property if any +// of the sub-storage are inefficient (thus making everything inefficient). template struct ArrayExtractComponentImpl> + : vtkm::cont::internal::ArrayExtractComponentImplInherit { template vtkm::cont::ArrayHandleStride AdjustStrideForComponent( diff --git a/vtkm/cont/ArrayHandleCompositeVector.h b/vtkm/cont/ArrayHandleCompositeVector.h index c7e22667e..0517ebe1c 100644 --- a/vtkm/cont/ArrayHandleCompositeVector.h +++ b/vtkm/cont/ArrayHandleCompositeVector.h @@ -507,16 +507,19 @@ struct ExtractComponentCompositeVecFunctor } // namespace detail +// Superclass will inherit the ArrayExtractComponentImplInefficient property if any +// of the sub-storage are inefficient (thus making everything inefficient). template struct ArrayExtractComponentImpl> + : vtkm::cont::internal::ArrayExtractComponentImplInherit { - template - typename detail::ExtractComponentCompositeVecFunctor::ResultArray operator()( - const vtkm::cont::ArrayHandle, - vtkm::cont::StorageTagCompositeVec>& src, + template + auto operator()( + const vtkm::cont::ArrayHandle>& src, vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy) const { + using T = typename vtkm::VecTraits::ComponentType; vtkm::cont::ArrayHandleCompositeVector...> array(src); constexpr vtkm::IdComponent NUM_SUB_COMPONENTS = vtkm::VecFlat::NUM_COMPONENTS; diff --git a/vtkm/cont/ArrayHandleConcatenate.h b/vtkm/cont/ArrayHandleConcatenate.h index b29d7abaa..866ad8092 100644 --- a/vtkm/cont/ArrayHandleConcatenate.h +++ b/vtkm/cont/ArrayHandleConcatenate.h @@ -248,12 +248,12 @@ public: return vtkm::cont::internal::CreateBuffers(array1, array2); } - VTKM_CONT static const ArrayHandleType1& GetArray1(const vtkm::cont::internal::Buffer* buffers) + VTKM_CONT static const ArrayHandleType1 GetArray1(const vtkm::cont::internal::Buffer* buffers) { return ArrayHandleType1(Buffers1(buffers)); } - VTKM_CONT static const ArrayHandleType2& GetArray2(const vtkm::cont::internal::Buffer* buffers) + VTKM_CONT static const ArrayHandleType2 GetArray2(const vtkm::cont::internal::Buffer* buffers) { return ArrayHandleType2(Buffers2(buffers)); } diff --git a/vtkm/cont/ArrayHandleCounting.h b/vtkm/cont/ArrayHandleCounting.h index a5cc3a39d..7f6f08e0d 100644 --- a/vtkm/cont/ArrayHandleCounting.h +++ b/vtkm/cont/ArrayHandleCounting.h @@ -138,6 +138,10 @@ public: internal::ArrayPortalCounting(start, step, length))) { } + + VTKM_CONT CountingValueType GetStart() const { return this->ReadPortal().GetStart(); } + + VTKM_CONT CountingValueType GetStep() const { return this->ReadPortal().GetStep(); } }; /// A convenience function for creating an ArrayHandleCounting. It takes the diff --git a/vtkm/cont/ArrayHandleGroupVec.h b/vtkm/cont/ArrayHandleGroupVec.h index c54be0f44..e77621867 100644 --- a/vtkm/cont/ArrayHandleGroupVec.h +++ b/vtkm/cont/ArrayHandleGroupVec.h @@ -249,9 +249,12 @@ VTKM_CONT vtkm::cont::ArrayHandleGroupVec make_ namespace internal { +// Superclass will inherit the ArrayExtractComponentImplInefficient property if +// the sub-storage is inefficient (thus making everything inefficient). template struct ArrayExtractComponentImpl< vtkm::cont::StorageTagGroupVec> + : vtkm::cont::internal::ArrayExtractComponentImpl { template vtkm::cont::ArrayHandleStride::BaseComponentType> operator()( diff --git a/vtkm/cont/ArrayHandlePermutation.h b/vtkm/cont/ArrayHandlePermutation.h index 1ad536904..0ab2a7788 100644 --- a/vtkm/cont/ArrayHandlePermutation.h +++ b/vtkm/cont/ArrayHandlePermutation.h @@ -216,6 +216,10 @@ class ArrayHandlePermutation VTKM_IS_ARRAY_HANDLE(IndexArrayHandleType); VTKM_IS_ARRAY_HANDLE(ValueArrayHandleType); + VTKM_STATIC_ASSERT_MSG( + (std::is_same::value), + "Permutation array in ArrayHandlePermutation must have vtkm::Id value type."); + public: VTKM_ARRAY_HANDLE_SUBCLASS( ArrayHandlePermutation, diff --git a/vtkm/cont/ArrayHandleReverse.h b/vtkm/cont/ArrayHandleReverse.h index a66ca9f07..61a0d9b8f 100644 --- a/vtkm/cont/ArrayHandleReverse.h +++ b/vtkm/cont/ArrayHandleReverse.h @@ -217,8 +217,11 @@ VTKM_CONT ArrayHandleReverse make_ArrayHandleReverse(const HandleTyp namespace internal { +// Superclass will inherit the ArrayExtractComponentImplInefficient property if +// the sub-storage is inefficient (thus making everything inefficient). template struct ArrayExtractComponentImpl> + : vtkm::cont::internal::ArrayExtractComponentImpl { template using StrideArrayType = diff --git a/vtkm/cont/ArrayHandleView.h b/vtkm/cont/ArrayHandleView.h index ae97a2396..90cc8a53f 100644 --- a/vtkm/cont/ArrayHandleView.h +++ b/vtkm/cont/ArrayHandleView.h @@ -179,7 +179,7 @@ public: vtkm::Id adjustedEndIndex = (endIndex < indices.NumberOfValues) ? endIndex + indices.StartIndex : indices.NumberOfValues + indices.StartIndex; - SourceStorage::Fill(buffers, fillValue, adjustedStartIndex, adjustedEndIndex, token); + SourceStorage::Fill(buffers + 1, fillValue, adjustedStartIndex, adjustedEndIndex, token); } VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers, @@ -258,8 +258,11 @@ ArrayHandleView make_ArrayHandleView(const ArrayHandleType& arr namespace internal { +// Superclass will inherit the ArrayExtractComponentImplInefficient property if +// the sub-storage is inefficient (thus making everything inefficient). template struct ArrayExtractComponentImpl> + : vtkm::cont::internal::ArrayExtractComponentImpl { template using StrideArrayType = diff --git a/vtkm/cont/ArrayHandleZip.h b/vtkm/cont/ArrayHandleZip.h index dcb649147..5598b0311 100644 --- a/vtkm/cont/ArrayHandleZip.h +++ b/vtkm/cont/ArrayHandleZip.h @@ -208,6 +208,15 @@ public: FirstStorage::CreateWritePortal(FirstArrayBuffers(buffers), device, token), SecondStorage::CreateWritePortal(SecondArrayBuffers(buffers), device, token)); } + + vtkm::cont::ArrayHandle GetFirstArray(const vtkm::cont::internal::Buffer* buffers) + { + return { FirstArrayBuffers(buffers) }; + } + vtkm::cont::ArrayHandle GetSecondArray(const vtkm::cont::internal::Buffer* buffers) + { + return { SecondArrayBuffers(buffers) }; + } }; } // namespace internal @@ -238,6 +247,15 @@ public: : Superclass(vtkm::cont::internal::CreateBuffers(firstArray, secondArray)) { } + + FirstHandleType GetFirstArray() const + { + return this->GetStorage().GetFirstArray(this->GetBuffers()); + } + SecondHandleType GetSecondArray() const + { + return this->GetStorage().GetSecondArray(this->GetBuffers()); + } }; /// A convenience function for creating an ArrayHandleZip. It takes the two diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index ea6235f77..e5f97f795 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -11,6 +11,7 @@ set(headers Algorithm.h ArrayCopy.h + ArrayCopyDevice.h ArrayExtractComponent.h ArrayGetValues.h ArrayHandle.h @@ -192,7 +193,9 @@ set(device_sources ColorTable.cxx ConvertNumComponentsToOffsets.cxx Field.cxx + internal/ArrayCopyUnknown.cxx internal/Buffer.cxx + internal/MapArrayPermutation.cxx MergePartitionedDataSet.cxx PointLocatorSparseGrid.cxx RuntimeDeviceInformation.cxx diff --git a/vtkm/cont/DataSetBuilderRectilinear.h b/vtkm/cont/DataSetBuilderRectilinear.h index f5debe7b1..d8a716bd4 100644 --- a/vtkm/cont/DataSetBuilderRectilinear.h +++ b/vtkm/cont/DataSetBuilderRectilinear.h @@ -10,6 +10,7 @@ #ifndef vtk_m_cont_DataSetBuilderRectilinear_h #define vtk_m_cont_DataSetBuilderRectilinear_h +#include #include #include #include @@ -34,7 +35,7 @@ class VTKM_CONT_EXPORT DataSetBuilderRectilinear VTKM_CONT static void CopyInto(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { - vtkm::cont::UnknownArrayHandle(output).DeepCopyFrom(input); + vtkm::cont::ArrayCopy(input, output); } template diff --git a/vtkm/cont/MergePartitionedDataSet.cxx b/vtkm/cont/MergePartitionedDataSet.cxx index 34a7a91ad..8b46dd436 100644 --- a/vtkm/cont/MergePartitionedDataSet.cxx +++ b/vtkm/cont/MergePartitionedDataSet.cxx @@ -9,6 +9,7 @@ //============================================================================ #include +#include #include #include #include diff --git a/vtkm/cont/ParticleArrayCopy.hxx b/vtkm/cont/ParticleArrayCopy.hxx index 529184195..8901d5104 100644 --- a/vtkm/cont/ParticleArrayCopy.hxx +++ b/vtkm/cont/ParticleArrayCopy.hxx @@ -12,7 +12,6 @@ #define vtk_m_cont_ParticleArrayCopy_hxx #include -#include #include #include #include @@ -84,7 +83,7 @@ VTKM_ALWAYS_EXPORT inline void ParticleArrayCopy( vtkm::cont::Algorithm::CopyIf(posTrn, termTrn, outPos); } else - vtkm::cont::ArrayCopy(posTrn, outPos); + vtkm::cont::Algorithm::Copy(posTrn, outPos); } diff --git a/vtkm/cont/PointLocatorSparseGrid.cxx b/vtkm/cont/PointLocatorSparseGrid.cxx index 342d3c4a5..bb7b31ea4 100644 --- a/vtkm/cont/PointLocatorSparseGrid.cxx +++ b/vtkm/cont/PointLocatorSparseGrid.cxx @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -82,9 +82,8 @@ void PointLocatorSparseGrid::Build() static_cast(this->Range[2].Max)); // generate unique id for each input point - vtkm::cont::ArrayHandleCounting pointCounting( - 0, 1, this->GetCoordinates().GetNumberOfValues()); - vtkm::cont::ArrayCopy(pointCounting, this->PointIds); + vtkm::cont::ArrayHandleIndex pointIndex(this->GetCoordinates().GetNumberOfValues()); + vtkm::cont::ArrayCopy(pointIndex, this->PointIds); using internal::BinPointsWorklet; diff --git a/vtkm/cont/UnknownArrayHandle.cxx b/vtkm/cont/UnknownArrayHandle.cxx index cc95461fd..1e15ccaf8 100644 --- a/vtkm/cont/UnknownArrayHandle.cxx +++ b/vtkm/cont/UnknownArrayHandle.cxx @@ -275,12 +275,32 @@ VTKM_CONT void UnknownArrayHandle::Allocate(vtkm::Id numValues, vtkm::CopyFlag p VTKM_CONT void UnknownArrayHandle::DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source) { - vtkm::cont::internal::ArrayCopyUnknown(source, *this); + if (!this->IsValid()) + { + *this = source.NewInstance(); + } + + const_cast(this)->DeepCopyFrom(source); } VTKM_CONT void UnknownArrayHandle::DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source) const { - vtkm::cont::internal::ArrayCopyUnknown(source, *this); + if (!this->IsValid()) + { + throw vtkm::cont::ErrorBadValue( + "Attempty to copy to a constant UnknownArrayHandle with no valid array."); + } + + if (source.IsValueTypeImpl(this->Container->ValueType) && + source.IsStorageTypeImpl(this->Container->StorageType)) + { + this->Container->DeepCopy(source.Container->ArrayHandlePointer, + this->Container->ArrayHandlePointer); + } + else + { + vtkm::cont::internal::ArrayCopyUnknown(source, *this); + } } VTKM_CONT @@ -290,8 +310,10 @@ void UnknownArrayHandle::CopyShallowIfPossible(const vtkm::cont::UnknownArrayHan { *this = source; } - - const_cast(this)->CopyShallowIfPossible(source); + else + { + const_cast(this)->CopyShallowIfPossible(source); + } } VTKM_CONT @@ -311,7 +333,7 @@ void UnknownArrayHandle::CopyShallowIfPossible(const vtkm::cont::UnknownArrayHan } else { - this->DeepCopyFrom(source); + vtkm::cont::internal::ArrayCopyUnknown(source, *this); } } diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index 44351af3e..a6469822b 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -113,6 +113,15 @@ void UnknownAHShallowCopy(const void* sourceMem, void* destinationMem) *destination = *source; } +template +void UnknownAHDeepCopy(const void* sourceMem, void* destinationMem) +{ + using AH = vtkm::cont::ArrayHandle; + const AH* source = reinterpret_cast(sourceMem); + AH* destination = reinterpret_cast(destinationMem); + destination->DeepCopyFrom(*source); +} + template std::vector UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy) @@ -224,6 +233,9 @@ struct VTKM_CONT_EXPORT UnknownAHContainer using ShallowCopyType = void(const void*, void*); ShallowCopyType* ShallowCopy; + using DeepCopyType = void(const void*, void*); + DeepCopyType* DeepCopy; + using ExtractComponentType = std::vector(void*, vtkm::IdComponent, vtkm::CopyFlag); @@ -331,6 +343,7 @@ inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle) , Allocate(detail::UnknownAHAllocate) , ShallowCopy(detail::UnknownAHShallowCopy) + , DeepCopy(detail::UnknownAHDeepCopy) , ExtractComponent(detail::UnknownAHExtractComponent) , ReleaseResources(detail::UnknownAHReleaseResources) , ReleaseResourcesExecution(detail::UnknownAHReleaseResourcesExecution) diff --git a/vtkm/cont/internal/ArrayCopyUnknown.cxx b/vtkm/cont/internal/ArrayCopyUnknown.cxx new file mode 100644 index 000000000..fdee4befc --- /dev/null +++ b/vtkm/cont/internal/ArrayCopyUnknown.cxx @@ -0,0 +1,254 @@ +//============================================================================ +// 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 + +#include + +namespace +{ + +// Use a worklet because device adapter copies often have an issue with casting the values from the +// `ArrayHandleRecomineVec` that comes from `UnknownArrayHandle::CastAndCallWithExtractedArray`. +struct CopyWorklet : vtkm::worklet::WorkletMapField +{ + using ControlSignature = void(FieldIn, FieldOut); + using ExecutionSignature = void(_1, _2); + using InputDomain = _1; + + template + VTKM_EXEC void operator()(const InType& in, OutType& out) const + { + out = in; + } +}; + +struct UnknownCopyOnDevice +{ + bool Called = false; + + template + void operator()(vtkm::cont::DeviceAdapterId device, + const vtkm::cont::ArrayHandleRecombineVec& in, + const vtkm::cont::ArrayHandleRecombineVec& out) + { + // Note: ArrayHandleRecombineVec returns the wrong value for IsOnDevice (always true). + // This is one of the consequences of ArrayHandleRecombineVec breaking assumptions of + // ArrayHandle. It does this by stuffing Buffer objects in another Buffer's meta data + // rather than listing them explicitly (where they can be queried). We get around this + // by pulling out one of the component arrays and querying that. + if (!this->Called && + ((device == vtkm::cont::DeviceAdapterTagAny{}) || + (in.GetComponentArray(0).IsOnDevice(device)))) + { + vtkm::cont::Invoker invoke(device); + invoke(CopyWorklet{}, in, out); + this->Called = true; + } + } +}; + +struct UnknownCopyFunctor2 +{ + template + void operator()(const vtkm::cont::ArrayHandleRecombineVec& out, + const vtkm::cont::ArrayHandleRecombineVec& in) const + { + UnknownCopyOnDevice doCopy; + + // Try to copy on a device that the data are already on. + vtkm::ListForEach(doCopy, VTKM_DEFAULT_DEVICE_ADAPTER_LIST{}, in, out); + + // If it was not on any device, call one more time with any adapter to copy wherever. + doCopy(vtkm::cont::DeviceAdapterTagAny{}, in, out); + } +}; + +struct UnknownCopyFunctor1 +{ + template + void operator()(const vtkm::cont::ArrayHandleRecombineVec& in, + const vtkm::cont::UnknownArrayHandle& out) const + { + out.Allocate(in.GetNumberOfValues()); + + this->DoIt(in, out, typename std::is_same::type{}); + } + + template + void DoIt(const vtkm::cont::ArrayHandleRecombineVec& in, + const vtkm::cont::UnknownArrayHandle& out, + std::false_type) const + { + // Source is not float. + if (out.IsBaseComponentType()) + { + // Arrays have the same base component type. Copy directly. + try + { + UnknownCopyFunctor2{}(out.ExtractArrayFromComponents(vtkm::CopyFlag::Off), in); + } + catch (vtkm::cont::Error& error) + { + throw vtkm::cont::ErrorBadType( + "Unable to copy to an array of type " + out.GetArrayTypeName() + + " using anonymous methods. Try using vtkm::cont::ArrayCopyDevice. " + "(Original error: `" + + error.GetMessage() + "')"); + } + } + else if (out.IsBaseComponentType()) + { + // Can copy anything to default float. + try + { + UnknownCopyFunctor2{}( + out.ExtractArrayFromComponents(vtkm::CopyFlag::Off), in); + } + catch (vtkm::cont::Error& error) + { + throw vtkm::cont::ErrorBadType( + "Unable to copy to an array of type " + out.GetArrayTypeName() + + " using anonymous methods. Try using vtkm::cont::ArrayCopyDevice. " + "(Original error: `" + + error.GetMessage() + "')"); + } + } + else + { + // Arrays have different base types. To reduce the number of template paths from nxn to 3n, + // copy first to a temp array of default float. + vtkm::cont::UnknownArrayHandle temp = out.NewInstanceFloatBasic(); + (*this)(in, temp); + vtkm::cont::ArrayCopy(temp, out); + } + } + + template + void DoIt(const vtkm::cont::ArrayHandleRecombineVec& in, + const vtkm::cont::UnknownArrayHandle& out, + std::true_type) const + { + // Source array is FloatDefault. That should be copiable to anything. + out.CastAndCallWithExtractedArray(UnknownCopyFunctor2{}, in); + } +}; + +void ArrayCopySpecialCase(const vtkm::cont::ArrayHandleIndex& source, + const vtkm::cont::UnknownArrayHandle& destination) +{ + if (destination.CanConvert()) + { + // Unlikely, but we'll check. + destination.AsArrayHandle().DeepCopyFrom(source); + } + else if (destination.IsBaseComponentType()) + { + destination.Allocate(source.GetNumberOfValues()); + auto dest = destination.ExtractComponent(0, vtkm::CopyFlag::Off); + vtkm::cont::ArrayCopyDevice(source, dest); + } + else if (destination.IsBaseComponentType()) + { + destination.Allocate(source.GetNumberOfValues()); + auto dest = destination.ExtractComponent(0, vtkm::CopyFlag::Off); + vtkm::cont::ArrayCopyDevice(source, dest); + } + else if (destination.CanConvert>()) + { + vtkm::cont::ArrayHandle dest; + destination.AsArrayHandle(dest); + vtkm::cont::ArrayCopyDevice(source, dest); + } + else + { + // Initializing something that is probably not really an index. Rather than trace down every + // unlikely possibility, just copy to float and then to the final array. + vtkm::cont::ArrayHandle dest; + vtkm::cont::ArrayCopyDevice(source, dest); + vtkm::cont::ArrayCopy(dest, destination); + } +} + +template +bool TryArrayCopySpecialCase(const vtkm::cont::UnknownArrayHandle& source, + const vtkm::cont::UnknownArrayHandle& destination) +{ + if (source.CanConvert()) + { + ArrayCopySpecialCase(source.AsArrayHandle(), destination); + return true; + } + else + { + return false; + } +} + +void DoUnknownArrayCopy(const vtkm::cont::UnknownArrayHandle& source, + const vtkm::cont::UnknownArrayHandle& destination) +{ + if (source.GetNumberOfValues() > 0) + { + // Try known special cases. + if (TryArrayCopySpecialCase(source, destination)) + { + return; + } + + source.CastAndCallWithExtractedArray(UnknownCopyFunctor1{}, destination); + } + else + { + destination.ReleaseResources(); + } +} + +} // anonymous namespace + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source, + vtkm::cont::UnknownArrayHandle& destination) +{ + if (!destination.IsValid()) + { + destination = source.NewInstanceBasic(); + } + + DoUnknownArrayCopy(source, destination); +} + +void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source, + const vtkm::cont::UnknownArrayHandle& destination) +{ + if (!destination.IsValid()) + { + throw vtkm::cont::ErrorBadValue( + "Attempty to copy to a constant UnknownArrayHandle with no valid array."); + } + + DoUnknownArrayCopy(source, destination); +} + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm diff --git a/vtkm/cont/internal/CMakeLists.txt b/vtkm/cont/internal/CMakeLists.txt index da2c3eb54..a12e02713 100644 --- a/vtkm/cont/internal/CMakeLists.txt +++ b/vtkm/cont/internal/CMakeLists.txt @@ -28,6 +28,7 @@ set(headers FunctorsGeneral.h IteratorFromArrayPortal.h KXSort.h + MapArrayPermutation.h OptionParser.h OptionParserArguments.h ParallelRadixSort.h diff --git a/vtkm/cont/internal/MapArrayPermutation.cxx b/vtkm/cont/internal/MapArrayPermutation.cxx new file mode 100644 index 000000000..cb3512df0 --- /dev/null +++ b/vtkm/cont/internal/MapArrayPermutation.cxx @@ -0,0 +1,100 @@ +//============================================================================ +// 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 +{ + +template +struct MapPermutationWorklet : vtkm::worklet::WorkletMapField +{ + T InvalidValue; + + explicit MapPermutationWorklet(T invalidValue) + : InvalidValue(invalidValue) + { + } + + using ControlSignature = void(FieldIn permutationIndex, WholeArrayIn input, FieldOut output); + + template + VTKM_EXEC void operator()(vtkm::Id permutationIndex, + InputPortalType inputPortal, + OutputType& output) const + { + VTKM_STATIC_ASSERT(vtkm::HasVecTraits::value); + if ((permutationIndex >= 0) && (permutationIndex < inputPortal.GetNumberOfValues())) + { + output = inputPortal.Get(permutationIndex); + } + else + { + output = this->InvalidValue; + } + } +}; + +struct DoMapFieldPermutation +{ + template + void operator()(const InputArrayType& input, + const PermutationArrayType& permutation, + vtkm::cont::UnknownArrayHandle& output, + vtkm::Float64 invalidValue) const + { + using BaseComponentType = typename InputArrayType::ValueType::ComponentType; + + MapPermutationWorklet worklet( + vtkm::cont::internal::CastInvalidValue(invalidValue)); + vtkm::cont::Invoker{}( + worklet, + permutation, + input, + output.ExtractArrayFromComponents(vtkm::CopyFlag::Off)); + } +}; + +} // anonymous namespace + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +vtkm::cont::UnknownArrayHandle MapArrayPermutation( + const vtkm::cont::UnknownArrayHandle& inputArray, + const vtkm::cont::UnknownArrayHandle& permutation, + vtkm::Float64 invalidValue) +{ + if (!permutation.IsBaseComponentType()) + { + throw vtkm::cont::ErrorBadType("Permutation array input to MapArrayPermutation must have " + "values of vtkm::Id. Reported type is " + + permutation.GetBaseComponentTypeName()); + } + vtkm::cont::UnknownArrayHandle outputArray = inputArray.NewInstanceBasic(); + outputArray.Allocate(permutation.GetNumberOfValues()); + inputArray.CastAndCallWithExtractedArray( + DoMapFieldPermutation{}, permutation.ExtractComponent(0), outputArray, invalidValue); + return outputArray; +} + +} +} +} // namespace vtkm::cont::internal diff --git a/vtkm/cont/internal/MapArrayPermutation.h b/vtkm/cont/internal/MapArrayPermutation.h new file mode 100644 index 000000000..393b7c5b1 --- /dev/null +++ b/vtkm/cont/internal/MapArrayPermutation.h @@ -0,0 +1,51 @@ +//============================================================================ +// 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_internal_MapArrayPermutation_h +#define vtk_m_cont_internal_MapArrayPermutation_h + +#include +#include + +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +/// Used to map a permutation like that found in an ArrayHandlePermutation. +/// +VTKM_CONT_EXPORT vtkm::cont::UnknownArrayHandle MapArrayPermutation( + const vtkm::cont::UnknownArrayHandle& inputArray, + const vtkm::cont::UnknownArrayHandle& permutation, + vtkm::Float64 invalidValue = vtkm::Nan64()); + +/// Used to map a permutation array. +/// +template +vtkm::cont::UnknownArrayHandle MapArrayPermutation( + const vtkm::cont::ArrayHandle>& + inputArray, + vtkm::Float64 invalidValue = vtkm::Nan64()) +{ + vtkm::cont::ArrayHandlePermutation, + vtkm::cont::ArrayHandle> + input = inputArray; + return MapArrayPermutation(input.GetValueArray(), input.GetIndexArray(), invalidValue); +} + +} +} +} // namespace vtkm::cont::internal + +#endif //vtk_m_cont_internal_MapArrayPermutation_h diff --git a/vtkm/cont/testing/Testing.cxx b/vtkm/cont/testing/Testing.cxx index f3dc57c2f..c4680f982 100644 --- a/vtkm/cont/testing/Testing.cxx +++ b/vtkm/cont/testing/Testing.cxx @@ -66,7 +66,7 @@ std::string Testing::WriteDirPath(const std::string& filename) void Testing::SetEnv(const std::string& var, const std::string& value) { static std::vector> envVars{}; -#ifdef _MSC_VER +#ifdef _WIN32 auto iter = envVars.emplace(envVars.end(), var, value); _putenv_s(iter->first.c_str(), iter->second.c_str()); #else @@ -76,7 +76,7 @@ void Testing::SetEnv(const std::string& var, const std::string& value) void Testing::UnsetEnv(const std::string& var) { -#ifdef _MSC_VER +#ifdef _WIN32 SetEnv(var, ""); #else unsetenv(var.c_str()); diff --git a/vtkm/cont/testing/TestingFancyArrayHandles.h b/vtkm/cont/testing/TestingFancyArrayHandles.h index 1a4086e39..e3f23fdef 100644 --- a/vtkm/cont/testing/TestingFancyArrayHandles.h +++ b/vtkm/cont/testing/TestingFancyArrayHandles.h @@ -426,7 +426,7 @@ private: SetPortal(basicArray.WritePortal()); vtkm::cont::ArrayHandleSOA soaArray; - vtkm::cont::ArrayCopy(basicArray, soaArray); + vtkm::cont::Invoker{}(PassThrough{}, basicArray, soaArray); VTKM_TEST_ASSERT(soaArray.GetNumberOfValues() == ARRAY_SIZE); for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; ++componentIndex) @@ -1085,13 +1085,13 @@ private: VTKM_EXEC void operator()(const InputType& input, vtkm::Id workIndex, vtkm::Id& dummyOut) const { using ComponentType = typename InputType::ComponentType; - vtkm::IdComponent expectedSize = static_cast(workIndex + 1); + vtkm::IdComponent expectedSize = static_cast(workIndex); if (expectedSize != input.GetNumberOfComponents()) { this->RaiseError("Got unexpected number of components."); } - vtkm::Id valueIndex = workIndex * (workIndex + 1) / 2; + vtkm::Id valueIndex = workIndex * (workIndex - 1) / 2; dummyOut = valueIndex; for (vtkm::IdComponent componentIndex = 0; componentIndex < expectedSize; componentIndex++) { @@ -1113,8 +1113,7 @@ private: vtkm::Id sourceArraySize; vtkm::cont::ArrayHandle numComponentsArray; - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleCounting(1, 1, ARRAY_SIZE), - numComponentsArray); + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray); vtkm::cont::ArrayHandle offsetsArray = vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, sourceArraySize); @@ -1147,13 +1146,13 @@ private: VTKM_EXEC void operator()(OutputType& output, vtkm::Id workIndex) const { using ComponentType = typename OutputType::ComponentType; - vtkm::IdComponent expectedSize = static_cast(workIndex + 1); + vtkm::IdComponent expectedSize = static_cast(workIndex); if (expectedSize != output.GetNumberOfComponents()) { this->RaiseError("Got unexpected number of components."); } - vtkm::Id valueIndex = workIndex * (workIndex + 1) / 2; + vtkm::Id valueIndex = workIndex * (workIndex - 1) / 2; for (vtkm::IdComponent componentIndex = 0; componentIndex < expectedSize; componentIndex++) { output[componentIndex] = TestValue(valueIndex, ComponentType()); @@ -1170,8 +1169,7 @@ private: vtkm::Id sourceArraySize; vtkm::cont::ArrayHandle numComponentsArray; - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleCounting(1, 1, ARRAY_SIZE), - numComponentsArray); + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray); vtkm::cont::ArrayHandle offsetsArray = vtkm::cont::ConvertNumComponentsToOffsets( numComponentsArray, sourceArraySize, DeviceAdapterTag()); @@ -1364,6 +1362,15 @@ private: //verify that the control portal works CheckPortal(view.ReadPortal()); + + //verify that filling works + const ValueType expected = TestValue(20, ValueType{}); + view.Fill(expected); + auto valuesPortal = values.ReadPortal(); + for (vtkm::Id index = length; index < 2 * length; ++index) + { + VTKM_TEST_ASSERT(valuesPortal.Get(index) == expected); + } } }; diff --git a/vtkm/cont/testing/UnitTestArrayCopy.cxx b/vtkm/cont/testing/UnitTestArrayCopy.cxx index daad8efe6..b913d3328 100644 --- a/vtkm/cont/testing/UnitTestArrayCopy.cxx +++ b/vtkm/cont/testing/UnitTestArrayCopy.cxx @@ -9,12 +9,18 @@ //============================================================================ #include +#include +#include #include +#include #include +#include +#include #include #include #include +#include #include @@ -23,13 +29,43 @@ namespace static constexpr vtkm::Id ARRAY_SIZE = 10; -template -void TestValues(const RefArrayType& refArray, const TestArrayType& testArray) +vtkm::cont::UnknownArrayHandle MakeComparable(const vtkm::cont::UnknownArrayHandle& array, + std::false_type) +{ + return array; +} + +template +vtkm::cont::UnknownArrayHandle MakeComparable(const vtkm::cont::ArrayHandle& array, + std::true_type) +{ + return array; +} + +template +vtkm::cont::UnknownArrayHandle MakeComparable(const ArrayType& array, std::true_type) +{ + vtkm::cont::ArrayHandle simpleArray; + vtkm::cont::ArrayCopyDevice(array, simpleArray); + return simpleArray; +} + +void TestValuesImpl(const vtkm::cont::UnknownArrayHandle& refArray, + const vtkm::cont::UnknownArrayHandle& testArray) { auto result = test_equal_ArrayHandles(refArray, testArray); VTKM_TEST_ASSERT(result, result.GetMergedMessage()); } +template +void TestValues(const RefArrayType& refArray, const TestArrayType& testArray) +{ + TestValuesImpl( + MakeComparable(refArray, typename vtkm::cont::internal::ArrayHandleCheck::type{}), + MakeComparable(testArray, + typename vtkm::cont::internal::ArrayHandleCheck::type{})); +} + template vtkm::cont::ArrayHandle MakeInputArray() { @@ -44,18 +80,20 @@ void TryCopy() { VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Trying type: " << vtkm::testing::TypeName::Name()); + using VTraits = vtkm::VecTraits; { std::cout << "implicit -> basic" << std::endl; vtkm::cont::ArrayHandleIndex input(ARRAY_SIZE); - vtkm::cont::ArrayHandle output; + vtkm::cont::ArrayHandle output; vtkm::cont::ArrayCopy(input, output); TestValues(input, output); } { std::cout << "basic -> basic" << std::endl; - vtkm::cont::ArrayHandle input = MakeInputArray(); + using SourceType = typename VTraits::template ReplaceComponentType; + vtkm::cont::ArrayHandle input = MakeInputArray(); vtkm::cont::ArrayHandle output; vtkm::cont::ArrayCopy(input, output); TestValues(input, output); @@ -90,30 +128,72 @@ void TryCopy() TestValues(input, output); } - using TypeList = vtkm::ListAppend>; - using StorageList = VTKM_DEFAULT_STORAGE_LIST; - using UnknownArray = vtkm::cont::UnknownArrayHandle; - using UncertainArray = vtkm::cont::UncertainArrayHandle; - { - std::cout << "unknown -> unknown" << std::endl; - UnknownArray input = MakeInputArray(); - UnknownArray output; - vtkm::cont::ArrayCopy(input, output); - TestValues(input, output); - } - - { - std::cout << "uncertain -> basic (same type)" << std::endl; - UncertainArray input = MakeInputArray(); + std::cout << "constant -> basic" << std::endl; + vtkm::cont::ArrayHandleConstant input(TestValue(2, ValueType{}), ARRAY_SIZE); vtkm::cont::ArrayHandle output; vtkm::cont::ArrayCopy(input, output); TestValues(input, output); } { - std::cout << "uncertain -> basic (different type)" << std::endl; - UncertainArray input = MakeInputArray(); + std::cout << "counting -> basic" << std::endl; + vtkm::cont::ArrayHandleCounting input(ValueType(-4), ValueType(3), ARRAY_SIZE); + vtkm::cont::ArrayHandle output; + vtkm::cont::ArrayCopy(input, output); + TestValues(input, output); + } + + { + std::cout << "view -> basic" << std::endl; + vtkm::cont::ArrayHandle input = MakeInputArray(); + auto viewInput = vtkm::cont::make_ArrayHandleView(input, 1, ARRAY_SIZE / 2); + vtkm::cont::ArrayHandle output; + vtkm::cont::ArrayCopy(input, output); + TestValues(input, output); + } + + { + std::cout << "concatinate -> basic" << std::endl; + vtkm::cont::ArrayHandle input1 = MakeInputArray(); + vtkm::cont::ArrayHandleConstant input2(TestValue(6, ValueType{}), ARRAY_SIZE / 2); + auto concatInput = vtkm::cont::make_ArrayHandleConcatenate(input1, input2); + vtkm::cont::ArrayHandle output; + vtkm::cont::ArrayCopy(concatInput, output); + TestValues(concatInput, output); + } + + { + std::cout << "permutation -> basic" << std::endl; + vtkm::cont::ArrayHandle indices; + vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleCounting(0, 2, ARRAY_SIZE / 2), + indices); + auto input = vtkm::cont::make_ArrayHandlePermutation(indices, MakeInputArray()); + vtkm::cont::ArrayHandle output; + vtkm::cont::ArrayCopy(input, output); + TestValues(input, output); + } + + { + std::cout << "unknown -> unknown" << std::endl; + vtkm::cont::UnknownArrayHandle input = MakeInputArray(); + vtkm::cont::UnknownArrayHandle output; + vtkm::cont::ArrayCopy(input, output); + TestValues(input, output); + } + + { + std::cout << "unknown -> basic (same type)" << std::endl; + vtkm::cont::UnknownArrayHandle input = MakeInputArray(); + vtkm::cont::ArrayHandle output; + vtkm::cont::ArrayCopy(input, output); + TestValues(input, output); + } + + { + std::cout << "unknown -> basic (different type)" << std::endl; + using SourceType = typename VTraits::template ReplaceComponentType; + vtkm::cont::UnknownArrayHandle input = MakeInputArray(); vtkm::cont::ArrayHandle output; vtkm::cont::ArrayCopy(input, output); TestValues(input, output); @@ -139,7 +219,8 @@ void TryCopy() { std::cout << "unknown.DeepCopyFrom(different type)" << std::endl; - vtkm::cont::ArrayHandle input = MakeInputArray(); + using SourceType = typename VTraits::template ReplaceComponentType; + vtkm::cont::ArrayHandle input = MakeInputArray(); vtkm::cont::ArrayHandle outputArray; vtkm::cont::UnknownArrayHandle(outputArray).DeepCopyFrom(input); TestValues(input, outputArray); @@ -166,7 +247,8 @@ void TryCopy() { std::cout << "unknown.CopyShallowIfPossible(different type)" << std::endl; - vtkm::cont::ArrayHandle input = MakeInputArray(); + using SourceType = typename VTraits::template ReplaceComponentType; + vtkm::cont::ArrayHandle input = MakeInputArray(); vtkm::cont::ArrayHandle outputArray; vtkm::cont::UnknownArrayHandle(outputArray).CopyShallowIfPossible(input); TestValues(input, outputArray); @@ -203,6 +285,8 @@ void TestArrayCopy() TryCopy(); TryCopy(); TryCopy(); + TryCopy(); + TryCopy(); TryArrayCopyShallowIfPossible(); } diff --git a/vtkm/cont/testing/UnitTestArrayHandleDecorator.cxx b/vtkm/cont/testing/UnitTestArrayHandleDecorator.cxx index e619a1546..4b3c8053e 100644 --- a/vtkm/cont/testing/UnitTestArrayHandleDecorator.cxx +++ b/vtkm/cont/testing/UnitTestArrayHandleDecorator.cxx @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -331,8 +332,8 @@ struct DecoratorTests } // Copy a constant array into the decorator. This should modify ah3Copy. - vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleConstant(ValueType{ 25 }, ARRAY_SIZE), - ahDecor); + vtkm::cont::ArrayCopyDevice(vtkm::cont::make_ArrayHandleConstant(ValueType{ 25 }, ARRAY_SIZE), + ahDecor); { // Accessing portal should give all 25s: auto portalDecor = ahDecor.ReadPortal(); @@ -390,7 +391,7 @@ struct DecoratorTests } vtkm::cont::ArrayHandle copiedInExec; - vtkm::cont::ArrayCopy(decorArray, copiedInExec); + vtkm::cont::ArrayCopyDevice(decorArray, copiedInExec); { auto copiedPortal = copiedInExec.ReadPortal(); auto countPortal = ahCount.ReadPortal(); diff --git a/vtkm/cont/testing/UnitTestArrayRangeCompute.cxx b/vtkm/cont/testing/UnitTestArrayRangeCompute.cxx index c5d858d27..1842e0d5e 100644 --- a/vtkm/cont/testing/UnitTestArrayRangeCompute.cxx +++ b/vtkm/cont/testing/UnitTestArrayRangeCompute.cxx @@ -8,7 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include #include @@ -84,13 +84,13 @@ void FillArray(vtkm::cont::ArrayHandle& array) using Traits = vtkm::VecTraits; vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS; - vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleConstant(T{}, ARRAY_SIZE), array); + array.AllocateAndFill(ARRAY_SIZE, vtkm::TypeTraits::ZeroInitialization()); for (vtkm::IdComponent component = 0; component < numComponents; ++component) { vtkm::cont::ArrayHandleRandomUniformReal randomArray(ARRAY_SIZE); auto dest = vtkm::cont::make_ArrayHandleExtractComponent(array, component); - vtkm::cont::ArrayCopy(randomArray, dest); + vtkm::cont::ArrayCopyDevice(randomArray, dest); } } diff --git a/vtkm/cont/testing/UnitTestCellSet.cxx b/vtkm/cont/testing/UnitTestCellSet.cxx index af018657f..cfe3fdb32 100644 --- a/vtkm/cont/testing/UnitTestCellSet.cxx +++ b/vtkm/cont/testing/UnitTestCellSet.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 #include @@ -143,16 +143,13 @@ auto PermutationArray = vtkm::cont::ArrayHandleCounting(0, 2, BaseLine vtkm::cont::CellSetExplicit<> MakeCellSetExplicit() { vtkm::cont::ArrayHandle shapes; - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant{ vtkm::CELL_SHAPE_HEXAHEDRON, - BaseLineNumberOfCells }, - shapes); + shapes.AllocateAndFill(BaseLineNumberOfCells, vtkm::CELL_SHAPE_HEXAHEDRON); vtkm::cont::ArrayHandle numIndices; - vtkm::cont::ArrayCopy( - vtkm::cont::ArrayHandleConstant{ 8, BaseLineNumberOfCells }, numIndices); + numIndices.AllocateAndFill(BaseLineNumberOfCells, 8); vtkm::cont::ArrayHandle connectivity; - vtkm::cont::ArrayCopy(BaseLineConnectivity, connectivity); + vtkm::cont::ArrayCopyDevice(BaseLineConnectivity, connectivity); auto offsets = vtkm::cont::ConvertNumComponentsToOffsets(numIndices); diff --git a/vtkm/filter/CMakeLists.txt b/vtkm/filter/CMakeLists.txt index 1c50a7fdf..655b19f8b 100644 --- a/vtkm/filter/CMakeLists.txt +++ b/vtkm/filter/CMakeLists.txt @@ -11,26 +11,40 @@ vtkm_add_instantiations(GradientInstantiations FILTER Gradient) set(deprecated_headers + CellSetConnectivity.h CleanGrid.h ClipWithField.h ClipWithImplicitFunction.h Contour.h + CrossProduct.h DotProduct.h + Entropy.h ExternalFaces.h + ExtractGeometry.h ExtractPoints.h ExtractStructured.h GenerateIds.h + GhostCellRemove.h + Histogram.h + ImageConnectivity.h + Mask.h MaskPoints.h + NDEntropy.h + NDHistogram.h + ParticleDensityCloudInCell.h + ParticleDensityNearestGridPoint.h Slice.h + Threshold.h ThresholdPoints.h ) + vtkm_declare_headers(${deprecated_headers}) + vtkm_declare_headers(${deprecated_headers}) set(common_headers CellAverage.h CellMeasures.h - ExtractGeometry.h FieldMetadata.h FilterCell.h FilterDataSet.h @@ -43,15 +57,12 @@ set(common_headers PolicyBase.h PolicyDefault.h TaskQueue.h - Threshold.h Instantiations.h ) set(common_header_template_sources CellAverage.hxx CellMeasures.hxx - ExtractGeometry.hxx - ExtractStructured.hxx FilterDataSet.hxx FilterDataSetWithField.hxx FilterField.hxx @@ -59,46 +70,30 @@ set(common_header_template_sources FilterParticleAdvection.hxx FilterTemporalParticleAdvection.hxx PointAverage.hxx - Threshold.hxx ) set(common_sources_device CellAverage.cxx - ExtractGeometry.cxx - ExtractStructured.cxx PointAverage.cxx - Threshold.cxx - ) +) set(extra_headers AmrArrays.h - CellSetConnectivity.h ComputeMoments.h ContourTreeUniformAugmented.h ContourTreeUniformDistributed.h ContourTreeUniform.h CoordinateSystemTransform.h CreateResult.h - CrossProduct.h - Entropy.h FieldSelection.h FieldToColors.h GhostCellClassify.h - GhostCellRemove.h - Histogram.h - ImageConnectivity.h ImageDifference.h ImageMedian.h Lagrangian.h LagrangianStructures.h - Mask.h MeshQuality.h MIRFilter.h - NDEntropy.h - NDHistogram.h - ParticleDensityBase.h - ParticleDensityCloudInCell.h - ParticleDensityNearestGridPoint.h ParticleAdvection.h Pathline.h PathParticle.h @@ -127,30 +122,19 @@ set(extra_headers set(extra_header_template_sources AmrArrays.hxx - CellSetConnectivity.hxx ComputeMoments.hxx ContourTreeUniformAugmented.hxx ContourTreeUniformDistributed.hxx ContourTreeUniform.hxx CoordinateSystemTransform.hxx - CrossProduct.hxx - Entropy.hxx FieldToColors.hxx GhostCellClassify.hxx - GhostCellRemove.hxx - Histogram.hxx - ImageConnectivity.hxx ImageDifference.hxx ImageMedian.hxx Lagrangian.hxx LagrangianStructures.hxx - Mask.hxx MeshQuality.hxx MIRFilter.hxx - NDEntropy.hxx - NDHistogram.hxx - ParticleDensityCloudInCell.hxx - ParticleDensityNearestGridPoint.hxx ParticleAdvection.hxx Pathline.hxx PathParticle.hxx @@ -273,7 +257,9 @@ target_link_libraries(vtkm_filter PUBLIC INTERFACE install(TARGETS vtkm_filter EXPORT ${VTKm_EXPORT_NAME}) add_subdirectory(clean_grid) +add_subdirectory(connected_components) add_subdirectory(contour) +add_subdirectory(density_estimate) add_subdirectory(entity_extraction) add_subdirectory(internal) add_subdirectory(particleadvection) diff --git a/vtkm/filter/CellSetConnectivity.h b/vtkm/filter/CellSetConnectivity.h index e3c073162..21f3ad13b 100644 --- a/vtkm/filter/CellSetConnectivity.h +++ b/vtkm/filter/CellSetConnectivity.h @@ -7,54 +7,34 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ +#ifndef vtk_m_filter_CellSetConnectivity_h +#define vtk_m_filter_CellSetConnectivity_h -#ifndef vtkm_m_filter_CellSetConnectivity_h -#define vtkm_m_filter_CellSetConnectivity_h - -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Finds groups of cells that are connected together through their topology. -/// -/// Finds and labels groups of cells that are connected together through their topology. -/// Two cells are considered connected if they share an edge. CellSetConnectivity identifies some -/// number of components and assigns each component a unique integer. -/// The result of the filter is a cell field of type vtkm::Id with the default name of 'component'. -/// Each entry in the cell field will be a number that identifies to which component the cell belongs. -class CellSetConnectivity : public vtkm::filter::FilterDataSet + +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/connected_components/CellSetConnectivity.h instead of " + "vtkm/filter/CellSetConnectivity.h.") +inline void CellSetConnectivity_deprecated() {} + +inline void CellSetConnectivity_deprecated_warning() { -public: - using SupportedTypes = vtkm::TypeListScalarAll; - VTKM_CONT CellSetConnectivity(); + CellSetConnectivity_deprecated(); +} - void SetOutputFieldName(const std::string& name) { this->OutputFieldName = name; } - - VTKM_CONT - const std::string& GetOutputFieldName() const { return this->OutputFieldName; } - - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy); - - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - const vtkm::filter::PolicyBase&) - { - result.AddField(field); - return true; - } - -private: - std::string OutputFieldName; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::connected_components::CellSetConnectivity.") + CellSetConnectivity : public vtkm::filter::connected_components::CellSetConnectivity +{ + using connected_components::CellSetConnectivity::CellSetConnectivity; }; -} -} -#include +} +} // namespace vtkm::filter -#endif //vtkm_m_filter_CellSetConnectivity_h +#endif //vtk_m_filter_CellSetConnectivity_h diff --git a/vtkm/filter/CellSetConnectivity.hxx b/vtkm/filter/CellSetConnectivity.hxx deleted file mode 100644 index f5a7c0591..000000000 --- a/vtkm/filter/CellSetConnectivity.hxx +++ /dev/null @@ -1,42 +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 vtkm_m_filter_CellSetConnectivity_hxx -#define vtkm_m_filter_CellSetConnectivity_hxx - -#include -#include - -namespace vtkm -{ -namespace filter -{ - -VTKM_CONT CellSetConnectivity::CellSetConnectivity() - : OutputFieldName("component") -{ -} - -template -inline VTKM_CONT vtkm::cont::DataSet CellSetConnectivity::DoExecute( - const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy) -{ - vtkm::cont::ArrayHandle component; - - vtkm::worklet::connectivity::CellSetConnectivity().Run( - vtkm::filter::ApplyPolicyCellSet(input.GetCellSet(), policy, *this), component); - - return CreateResultFieldCell(input, component, this->GetOutputFieldName()); -} -} -} - -#endif //vtkm_m_filter_CellSetConnectivity_hxx diff --git a/vtkm/filter/CrossProduct.h b/vtkm/filter/CrossProduct.h index 879344550..381047b74 100644 --- a/vtkm/filter/CrossProduct.h +++ b/vtkm/filter/CrossProduct.h @@ -11,133 +11,31 @@ #ifndef vtk_m_filter_CrossProduct_h #define vtk_m_filter_CrossProduct_h -#include -#include +#include +#include namespace vtkm { namespace filter { -class CrossProduct : public vtkm::filter::FilterField +VTKM_DEPRECATED( + 1.8, + "Use vtkm/filter/vector_calculus/CrossProduct.h instead of vtkm/filter/CrossProduct.h.") +inline void CrossProduct_deprecated() {} + +inline void CrossProduct_deprecated_warning() { -public: - //CrossProduct filter only works on vec3 data. - using SupportedTypes = vtkm::TypeListFieldVec3; + CrossProduct_deprecated(); +} - VTKM_CONT - CrossProduct(); - - //@{ - /// Choose the primary field to operate on. In the cross product operation A x B, A is - /// the primary field. - VTKM_CONT - void SetPrimaryField( - const std::string& name, - vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) - { - this->SetActiveField(name, association); - } - - VTKM_CONT const std::string& GetPrimaryFieldName() const { return this->GetActiveFieldName(); } - VTKM_CONT vtkm::cont::Field::Association GetPrimaryFieldAssociation() const - { - return this->GetActiveFieldAssociation(); - } - //@} - - //@{ - /// When set to true, uses a coordinate system as the primary field instead of the one selected - /// by name. Use SetPrimaryCoordinateSystem to select which coordinate system. - VTKM_CONT - void SetUseCoordinateSystemAsPrimaryField(bool flag) - { - this->SetUseCoordinateSystemAsField(flag); - } - VTKM_CONT - bool GetUseCoordinateSystemAsPrimaryField() const - { - return this->GetUseCoordinateSystemAsField(); - } - //@} - - //@{ - /// Select the coordinate system index to use as the primary field. This only has an effect when - /// UseCoordinateSystemAsPrimaryField is true. - VTKM_CONT - void SetPrimaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(index); } - VTKM_CONT - vtkm::Id GetPrimaryCoordinateSystemIndex() const - { - return this->GetActiveCoordinateSystemIndex(); - } - //@} - - //@{ - /// Choose the secondary field to operate on. In the cross product operation A x B, B is - /// the secondary field. - VTKM_CONT - void SetSecondaryField( - const std::string& name, - vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) - { - this->SecondaryFieldName = name; - this->SecondaryFieldAssociation = association; - } - - VTKM_CONT const std::string& GetSecondaryFieldName() const { return this->SecondaryFieldName; } - VTKM_CONT vtkm::cont::Field::Association GetSecondaryFieldAssociation() const - { - return this->SecondaryFieldAssociation; - } - //@} - - //@{ - /// When set to true, uses a coordinate system as the primary field instead of the one selected - /// by name. Use SetPrimaryCoordinateSystem to select which coordinate system. - VTKM_CONT - void SetUseCoordinateSystemAsSecondaryField(bool flag) - { - this->UseCoordinateSystemAsSecondaryField = flag; - } - VTKM_CONT - bool GetUseCoordinateSystemAsSecondaryField() const - { - return this->UseCoordinateSystemAsSecondaryField; - } - //@} - - //@{ - /// Select the coordinate system index to use as the primary field. This only has an effect when - /// UseCoordinateSystemAsPrimaryField is true. - VTKM_CONT - void SetSecondaryCoordinateSystem(vtkm::Id index) - { - this->SecondaryCoordinateSystemIndex = index; - } - VTKM_CONT - vtkm::Id GetSecondaryCoordinateSystemIndex() const - { - return this->SecondaryCoordinateSystemIndex; - } - //@} - - template - VTKM_CONT vtkm::cont::DataSet DoExecute( - const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle, StorageType>& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); - -private: - std::string SecondaryFieldName; - vtkm::cont::Field::Association SecondaryFieldAssociation; - bool UseCoordinateSystemAsSecondaryField; - vtkm::Id SecondaryCoordinateSystemIndex; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::vector_calculus::CrossProduct.") CrossProduct + : public vtkm::filter::vector_calculus::CrossProduct +{ + using vector_calculus::CrossProduct::CrossProduct; }; + } } // namespace vtkm::filter -#include - #endif // vtk_m_filter_CrossProduct_h diff --git a/vtkm/filter/CrossProduct.hxx b/vtkm/filter/CrossProduct.hxx deleted file mode 100644 index a682f8c66..000000000 --- a/vtkm/filter/CrossProduct.hxx +++ /dev/null @@ -1,62 +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_filter_CrossProduct_hxx -#define vtk_m_filter_CrossProduct_hxx - -#include - -#include - -namespace vtkm -{ -namespace filter -{ - -//----------------------------------------------------------------------------- -inline VTKM_CONT CrossProduct::CrossProduct() - : vtkm::filter::FilterField() - , SecondaryFieldName() - , SecondaryFieldAssociation(vtkm::cont::Field::Association::ANY) - , UseCoordinateSystemAsSecondaryField(false) - , SecondaryCoordinateSystemIndex(0) -{ - this->SetOutputFieldName("crossproduct"); -} - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT vtkm::cont::DataSet CrossProduct::DoExecute( - const vtkm::cont::DataSet& inDataSet, - const vtkm::cont::ArrayHandle, StorageType>& primary, - const vtkm::filter::FieldMetadata& fieldMetadata, - vtkm::filter::PolicyBase policy) -{ - vtkm::cont::Field secondaryField; - if (this->UseCoordinateSystemAsSecondaryField) - { - secondaryField = inDataSet.GetCoordinateSystem(this->GetSecondaryCoordinateSystemIndex()); - } - else - { - secondaryField = inDataSet.GetField(this->SecondaryFieldName, this->SecondaryFieldAssociation); - } - auto secondary = - vtkm::filter::ApplyPolicyFieldOfType>(secondaryField, policy, *this); - - vtkm::cont::ArrayHandle> output; - this->Invoke(vtkm::worklet::CrossProduct{}, primary, secondary, output); - - return CreateResult(inDataSet, output, this->GetOutputFieldName(), fieldMetadata); -} -} -} // namespace vtkm::filter - -#endif diff --git a/vtkm/filter/Entropy.h b/vtkm/filter/Entropy.h index 0724caa28..a2e5163d0 100644 --- a/vtkm/filter/Entropy.h +++ b/vtkm/filter/Entropy.h @@ -7,47 +7,32 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_Entropy_h #define vtk_m_filter_Entropy_h -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Construct the entropy histogram of a given Field -/// -/// Construct a histogram which is used to compute the entropy with a default of 10 bins -/// -class Entropy : public vtkm::filter::FilterField +VTKM_DEPRECATED(1.8, "Use vtkm/filter/density_estimate/Entropy.h instead of vtkm/filter/Entropy.h.") +inline void Entropy_deprecated() {} + +inline void Entropy_deprecated_warning() { -public: - //currently the Entropy filter only works on scalar data. - using SupportedTypes = TypeListScalarAll; + Entropy_deprecated(); +} - //Construct a histogram which is used to compute the entropy with a default of 10 bins - VTKM_CONT - Entropy(); - - VTKM_CONT - void SetNumberOfBins(vtkm::Id count) { this->NumberOfBins = count; } - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - const vtkm::filter::PolicyBase& policy); - -private: - vtkm::Id NumberOfBins; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::density_estimate::Entropy.") Entropy + : public vtkm::filter::density_estimate::Entropy +{ + using density_estimate::Entropy::Entropy; }; + } } // namespace vtkm::filter - -#include - -#endif // vtk_m_filter_Entropy_h +#endif //vtk_m_filter_Entropy_h diff --git a/vtkm/filter/Entropy.hxx b/vtkm/filter/Entropy.hxx deleted file mode 100644 index 579f91c60..000000000 --- a/vtkm/filter/Entropy.hxx +++ /dev/null @@ -1,50 +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_filter_Entropy_hxx -#define vtk_m_filter_Entropy_hxx - -#include - -namespace vtkm -{ -namespace filter -{ - -//----------------------------------------------------------------------------- -inline VTKM_CONT Entropy::Entropy() - : NumberOfBins(10) -{ - this->SetOutputFieldName("entropy"); -} - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT vtkm::cont::DataSet Entropy::DoExecute( - const vtkm::cont::DataSet& inDataSet, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMetadata, - const vtkm::filter::PolicyBase&) -{ - vtkm::worklet::FieldEntropy worklet; - - vtkm::Float64 e = worklet.Run(field, this->NumberOfBins); - - //the entropy vector only contain one element, the entorpy of the input field - vtkm::cont::ArrayHandle entropy; - entropy.Allocate(1); - entropy.WritePortal().Set(0, e); - - return CreateResult(inDataSet, entropy, this->GetOutputFieldName(), fieldMetadata); -} -} -} // namespace vtkm::filter - -#endif diff --git a/vtkm/filter/ExtractGeometry.cxx b/vtkm/filter/ExtractGeometry.cxx deleted file mode 100644 index 2ad4287a8..000000000 --- a/vtkm/filter/ExtractGeometry.cxx +++ /dev/null @@ -1,60 +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. -//============================================================================ -#define vtkm_filter_ExtractGeometry_cxx - -#include -#include - -#include - -namespace vtkm -{ -namespace filter -{ - -//----------------------------------------------------------------------------- -ExtractGeometry::ExtractGeometry() - : vtkm::filter::FilterDataSet() - , ExtractInside(true) - , ExtractBoundaryCells(false) - , ExtractOnlyBoundaryCells(false) -{ -} - -bool ExtractGeometry::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) -{ - if (field.IsFieldPoint()) - { - result.AddField(field); - return true; - } - else if (field.IsFieldCell()) - { - vtkm::cont::ArrayHandle permutation = this->Worklet.GetValidCellIds(); - return vtkm::filter::MapFieldPermutation(field, permutation, result); - } - else if (field.IsFieldGlobal()) - { - result.AddField(field); - return true; - } - else - { - return false; - } -} - -//----------------------------------------------------------------------------- -template VTKM_FILTER_COMMON_TEMPLATE_EXPORT vtkm::cont::DataSet ExtractGeometry::DoExecute( - const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase policy); -} -} // namespace vtkm::filter diff --git a/vtkm/filter/ExtractGeometry.h b/vtkm/filter/ExtractGeometry.h index a203aa1ce..869863c83 100644 --- a/vtkm/filter/ExtractGeometry.h +++ b/vtkm/filter/ExtractGeometry.h @@ -7,105 +7,34 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_ExtractGeometry_h #define vtk_m_filter_ExtractGeometry_h -#include - -#include -#include -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Extract a subset of geometry based on an implicit function -/// -/// Extracts from its input geometry all cells that are either -/// completely inside or outside of a specified implicit function. Any type of -/// data can be input to this filter. -/// -/// To use this filter you must specify an implicit function. You must also -/// specify whether to extract cells laying inside or outside of the implicit -/// function. (The inside of an implicit function is the negative values -/// region.) An option exists to extract cells that are neither inside or -/// outside (i.e., boundary). -/// -/// This differs from Clip in that Clip will subdivide boundary cells into new -/// cells, while this filter will not, producing a more 'crinkly' output. -/// -class VTKM_FILTER_COMMON_EXPORT ExtractGeometry - : public vtkm::filter::FilterDataSet +VTKM_DEPRECATED( + 1.8, + "Use vtkm/filter/entity_extraction/ExtractGeometry.h instead of vtkm/filter/ExtractGeometry.h.") +inline void ExtractGeometry_deprecated() {} + +inline void ExtractGeometry_deprecated_warning() { -public: - //currently the ExtractGeometry filter only works on scalar data. - using SupportedTypes = TypeListScalarAll; + ExtractGeometry_deprecated(); +} - VTKM_CONT ExtractGeometry(); - - // Set the volume of interest to extract - void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; } - - const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; } - - VTKM_CONT - bool GetExtractInside() { return this->ExtractInside; } - VTKM_CONT - void SetExtractInside(bool value) { this->ExtractInside = value; } - VTKM_CONT - void ExtractInsideOn() { this->ExtractInside = true; } - VTKM_CONT - void ExtractInsideOff() { this->ExtractInside = false; } - - VTKM_CONT - bool GetExtractBoundaryCells() { return this->ExtractBoundaryCells; } - VTKM_CONT - void SetExtractBoundaryCells(bool value) { this->ExtractBoundaryCells = value; } - VTKM_CONT - void ExtractBoundaryCellsOn() { this->ExtractBoundaryCells = true; } - VTKM_CONT - void ExtractBoundaryCellsOff() { this->ExtractBoundaryCells = false; } - - VTKM_CONT - bool GetExtractOnlyBoundaryCells() { return this->ExtractOnlyBoundaryCells; } - VTKM_CONT - void SetExtractOnlyBoundaryCells(bool value) { this->ExtractOnlyBoundaryCells = value; } - VTKM_CONT - void ExtractOnlyBoundaryCellsOn() { this->ExtractOnlyBoundaryCells = true; } - VTKM_CONT - void ExtractOnlyBoundaryCellsOff() { this->ExtractOnlyBoundaryCells = false; } - - template - vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy); - - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field); - - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase) - { - return this->MapFieldOntoOutput(result, field); - } - -private: - bool ExtractInside; - bool ExtractBoundaryCells; - bool ExtractOnlyBoundaryCells; - vtkm::ImplicitFunctionGeneral Function; - vtkm::worklet::ExtractGeometry Worklet; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::ExtractGeometry.") ExtractGeometry + : public vtkm::filter::entity_extraction::ExtractGeometry +{ + using entity_extraction::ExtractGeometry::ExtractGeometry; }; -#ifndef vtkm_filter_ExtractGeometry_cxx -extern template VTKM_FILTER_COMMON_TEMPLATE_EXPORT vtkm::cont::DataSet ExtractGeometry::DoExecute( - const vtkm::cont::DataSet&, - vtkm::filter::PolicyBase); -#endif } } // namespace vtkm::filter -#endif // vtk_m_filter_ExtractGeometry_h +#endif //vtk_m_filter_ExtractGeometry_h diff --git a/vtkm/filter/ExtractStructured.cxx b/vtkm/filter/ExtractStructured.cxx deleted file mode 100644 index 17145b549..000000000 --- a/vtkm/filter/ExtractStructured.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. -//============================================================================ -#define vtkm_filter_ExtractStructured_cxx -#include -#include - -#include - -namespace vtkm -{ -namespace filter -{ - -//----------------------------------------------------------------------------- -ExtractStructured::ExtractStructured() - : vtkm::filter::FilterDataSet() - , VOI(vtkm::RangeId3(0, -1, 0, -1, 0, -1)) - , SampleRate(vtkm::Id3(1, 1, 1)) - , IncludeBoundary(false) - , IncludeOffset(false) - , Worklet() -{ -} - -//----------------------------------------------------------------------------- -bool ExtractStructured::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) -{ - if (field.IsFieldPoint()) - { - return vtkm::filter::MapFieldPermutation(field, this->PointFieldMap, result); - } - else if (field.IsFieldCell()) - { - return vtkm::filter::MapFieldPermutation(field, this->CellFieldMap, result); - } - else if (field.IsFieldGlobal()) - { - result.AddField(field); - return true; - } - else - { - return false; - } -} - -//----------------------------------------------------------------------------- -void ExtractStructured::PostExecute(const vtkm::cont::PartitionedDataSet&, - vtkm::cont::PartitionedDataSet&) -{ - this->CellFieldMap.ReleaseResources(); - this->PointFieldMap.ReleaseResources(); -} - -//----------------------------------------------------------------------------- -template VTKM_FILTER_COMMON_TEMPLATE_EXPORT vtkm::cont::DataSet ExtractStructured::DoExecute( - const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase policy); -} -} diff --git a/vtkm/filter/ExtractStructured.h b/vtkm/filter/ExtractStructured.h index c8e392438..a92bddd6b 100644 --- a/vtkm/filter/ExtractStructured.h +++ b/vtkm/filter/ExtractStructured.h @@ -7,126 +7,35 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_ExtractStructured_h #define vtk_m_filter_ExtractStructured_h -#include - -#include -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Select piece (e.g., volume of interest) and/or subsample structured points dataset -/// -/// Select or subsample a portion of an input structured dataset. The selected -/// portion of interested is referred to as the Volume Of Interest, or VOI. -/// The output of this filter is a structured dataset. The filter treats input -/// data of any topological dimension (i.e., point, line, plane, or volume) and -/// can generate output data of any topological dimension. -/// -/// To use this filter set the VOI ivar which are i-j-k min/max indices that -/// specify a rectangular region in the data. (Note that these are 0-offset.) -/// You can also specify a sampling rate to subsample the data. -/// -/// Typical applications of this filter are to extract a slice from a volume -/// for image processing, subsampling large volumes to reduce data size, or -/// extracting regions of a volume with interesting data. -/// -class VTKM_FILTER_COMMON_EXPORT ExtractStructured - : public vtkm::filter::FilterDataSet + +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/entity_extraction/ExtractStructured.h instead of " + "vtkm/filter/ExtractStructured.h.") +inline void ExtractStructured_deprecated() {} + +inline void ExtractStructured_deprecated_warning() { -public: - ExtractStructured(); + ExtractStructured_deprecated(); +} - // Set the bounding box for the volume of interest - VTKM_CONT - vtkm::RangeId3 GetVOI() const { return this->VOI; } - - VTKM_CONT - void SetVOI(vtkm::Id i0, vtkm::Id i1, vtkm::Id j0, vtkm::Id j1, vtkm::Id k0, vtkm::Id k1) - { - this->VOI = vtkm::RangeId3(i0, i1, j0, j1, k0, k1); - } - VTKM_CONT - void SetVOI(vtkm::Id extents[6]) { this->VOI = vtkm::RangeId3(extents); } - VTKM_CONT - void SetVOI(vtkm::Id3 minPoint, vtkm::Id3 maxPoint) - { - this->VOI = vtkm::RangeId3(minPoint, maxPoint); - } - VTKM_CONT - void SetVOI(const vtkm::RangeId3& voi) { this->VOI = voi; } - - /// Get the Sampling rate - VTKM_CONT - vtkm::Id3 GetSampleRate() const { return this->SampleRate; } - - /// Set the Sampling rate - VTKM_CONT - void SetSampleRate(vtkm::Id i, vtkm::Id j, vtkm::Id k) { this->SampleRate = vtkm::Id3(i, j, k); } - - /// Set the Sampling rate - VTKM_CONT - void SetSampleRate(vtkm::Id3 sampleRate) { this->SampleRate = sampleRate; } - - /// Get if we should include the outer boundary on a subsample - VTKM_CONT - bool GetIncludeBoundary() { return this->IncludeBoundary; } - /// Set if we should include the outer boundary on a subsample - VTKM_CONT - void SetIncludeBoundary(bool value) { this->IncludeBoundary = value; } - - VTKM_CONT - void SetIncludeOffset(bool value) { this->IncludeOffset = value; } - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy); - - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field); - - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase) - { - return this->MapFieldOntoOutput(result, field); - } - - - VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet&, - vtkm::cont::PartitionedDataSet&); - - template - VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input, - vtkm::cont::PartitionedDataSet& output, - const vtkm::filter::PolicyBase&) - { - this->PostExecute(input, output); - } - -private: - vtkm::RangeId3 VOI; - vtkm::Id3 SampleRate = { 1, 1, 1 }; - bool IncludeBoundary; - bool IncludeOffset; - vtkm::worklet::ExtractStructured Worklet; - - vtkm::cont::ArrayHandle CellFieldMap; - vtkm::cont::ArrayHandle PointFieldMap; +class VTKM_DEPRECATED(1.8, + "Use vtkm::filter::entity_extraction::ExtractStructured.") ExtractStructured + : public vtkm::filter::entity_extraction::ExtractStructured +{ + using entity_extraction::ExtractStructured::ExtractStructured; }; -#ifndef vtkm_filter_ExtractStructured_cxx -extern template VTKM_FILTER_COMMON_TEMPLATE_EXPORT vtkm::cont::DataSet ExtractStructured::DoExecute( - const vtkm::cont::DataSet&, - vtkm::filter::PolicyBase); -#endif } } // namespace vtkm::filter - -#endif // vtk_m_filter_ExtractStructured_h +#endif //vtk_m_filter_ExtractStructured_h diff --git a/vtkm/filter/ExtractStructured.hxx b/vtkm/filter/ExtractStructured.hxx deleted file mode 100644 index 96247ca25..000000000 --- a/vtkm/filter/ExtractStructured.hxx +++ /dev/null @@ -1,52 +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_filter_ExtractStructured_hxx -#define vtk_m_filter_ExtractStructured_hxx -#include - -namespace vtkm -{ -namespace filter -{ -//----------------------------------------------------------------------------- -template -vtkm::cont::DataSet ExtractStructured::DoExecute(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy) -{ - const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); - const vtkm::cont::CoordinateSystem& coordinates = input.GetCoordinateSystem(); - - auto cellset = this->Worklet.Run(vtkm::filter::ApplyPolicyCellSetStructured(cells, policy, *this), - this->VOI, - this->SampleRate, - this->IncludeBoundary, - this->IncludeOffset); - - auto coords = this->Worklet.MapCoordinates(coordinates); - vtkm::cont::CoordinateSystem outputCoordinates(coordinates.GetName(), coords); - - vtkm::cont::DataSet output; - output.SetCellSet(vtkm::cont::UnknownCellSet(cellset)); - output.AddCoordinateSystem(outputCoordinates); - - // Create map arrays for mapping fields. Could potentially save some time to first check to see - // if these arrays would be used. - this->CellFieldMap = - this->Worklet.ProcessCellField(vtkm::cont::ArrayHandleIndex(input.GetNumberOfCells())); - this->PointFieldMap = - this->Worklet.ProcessPointField(vtkm::cont::ArrayHandleIndex(input.GetNumberOfPoints())); - - return output; -} -} -} - -#endif diff --git a/vtkm/filter/GhostCellRemove.h b/vtkm/filter/GhostCellRemove.h index 84806fc5c..59fd8f5fe 100644 --- a/vtkm/filter/GhostCellRemove.h +++ b/vtkm/filter/GhostCellRemove.h @@ -7,79 +7,34 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_GhostCellRemove_h #define vtk_m_filter_GhostCellRemove_h -#include -#include -#include +#include +#include namespace vtkm { namespace filter { -struct GhostCellRemovePolicy : vtkm::filter::PolicyBase +VTKM_DEPRECATED( + 1.8, + "Use vtkm/filter/entity_extraction/GhostCellRemove.h instead of vtkm/filter/GhostCellRemove.h.") +inline void GhostCellRemove_deprecated() {} + +inline void GhostCellRemove_deprecated_warning() { - using FieldTypeList = vtkm::List; + GhostCellRemove_deprecated(); +} + +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::GhostCellRemove.") GhostCellRemove + : public vtkm::filter::entity_extraction::GhostCellRemove +{ + using entity_extraction::GhostCellRemove::GhostCellRemove; }; -/// \brief Removes ghost cells -/// -class GhostCellRemove : public vtkm::filter::FilterDataSetWithField -{ -public: - //currently the GhostCellRemove filter only works on uint8 data. - using SupportedTypes = vtkm::List; - - VTKM_CONT - GhostCellRemove(); - - VTKM_CONT - void RemoveGhostField() { this->RemoveField = true; } - VTKM_CONT - void RemoveAllGhost() { this->RemoveAll = true; } - VTKM_CONT - void RemoveByType(const vtkm::UInt8& vals) - { - this->RemoveAll = false; - this->RemoveVals = vals; - } - VTKM_CONT - bool GetRemoveGhostField() { return this->RemoveField; } - VTKM_CONT - bool GetRemoveAllGhost() const { return this->RemoveAll; } - - VTKM_CONT - bool GetRemoveByType() const { return !this->RemoveAll; } - VTKM_CONT - vtkm::UInt8 GetRemoveType() const { return this->RemoveVals; } - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); - - //Map a new field onto the resulting dataset after running the filter - //this call is only valid after DoExecute is run - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase policy); - -private: - bool RemoveAll; - bool RemoveField; - vtkm::UInt8 RemoveVals; - vtkm::worklet::Threshold Worklet; -}; } } // namespace vtkm::filter -#ifndef vtk_m_filter_GhostCellRemove_hxx -#include -#endif - -#endif // vtk_m_filter_GhostCellRemove_h +#endif //vtk_m_filter_GhostCellRemove_h diff --git a/vtkm/filter/Histogram.h b/vtkm/filter/Histogram.h index 417865100..6ad4e2bb0 100644 --- a/vtkm/filter/Histogram.h +++ b/vtkm/filter/Histogram.h @@ -7,86 +7,33 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_Histogram_h #define vtk_m_filter_Histogram_h -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Construct the histogram of a given Field -/// -/// Construct a histogram with a default of 10 bins. -/// -class Histogram : public vtkm::filter::FilterField +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/density_estimate/Histogram.h instead of vtkm/filter/Histogram.h.") +inline void Histogram_deprecated() {} + +inline void Histogram_deprecated_warning() { -public: - using SupportedTypes = vtkm::TypeListScalarAll; + Histogram_deprecated(); +} - //Construct a histogram with a default of 10 bins - VTKM_CONT - Histogram(); - - VTKM_CONT - void SetNumberOfBins(vtkm::Id count) { this->NumberOfBins = count; } - - VTKM_CONT - vtkm::Id GetNumberOfBins() const { return this->NumberOfBins; } - - //@{ - /// Get/Set the range to use to generate the histogram. If range is set to - /// empty, the field's global range (computed using `vtkm::cont::FieldRangeGlobalCompute`) - /// will be used. - VTKM_CONT - void SetRange(const vtkm::Range& range) { this->Range = range; } - - VTKM_CONT - const vtkm::Range& GetRange() const { return this->Range; } - //@} - - /// Returns the bin delta of the last computed field. - VTKM_CONT - vtkm::Float64 GetBinDelta() const { return this->BinDelta; } - - /// Returns the range used for most recent execute. If `SetRange` is used to - /// specify and non-empty range, then this will be same as the range after - /// the `Execute` call. - VTKM_CONT - vtkm::Range GetComputedRange() const { return this->ComputedRange; } - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); - - //@{ - /// when operating on vtkm::cont::PartitionedDataSet, we - /// want to do processing across ranks as well. Just adding pre/post handles - /// for the same does the trick. - template - VTKM_CONT void PreExecute(const vtkm::cont::PartitionedDataSet& input, - const vtkm::filter::PolicyBase& policy); - - template - VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input, - vtkm::cont::PartitionedDataSet& output, - const vtkm::filter::PolicyBase&); - //@} - -private: - vtkm::Id NumberOfBins; - vtkm::Float64 BinDelta; - vtkm::Range ComputedRange; - vtkm::Range Range; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::density_estimate::Histogram.") Histogram + : public vtkm::filter::density_estimate::Histogram +{ + using density_estimate::Histogram::Histogram; }; + } } // namespace vtkm::filter -#include - -#endif // vtk_m_filter_Histogram_h +#endif //vtk_m_filter_Histogram_h diff --git a/vtkm/filter/ImageConnectivity.h b/vtkm/filter/ImageConnectivity.h index c069c63b7..704f82dd5 100644 --- a/vtkm/filter/ImageConnectivity.h +++ b/vtkm/filter/ImageConnectivity.h @@ -7,43 +7,34 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_ImageConnectivity_h #define vtk_m_filter_ImageConnectivity_h -#include -#include +#include +#include -/// \brief Groups connected points that have the same field value -/// -/// -/// The ImageConnectivity filter finds groups of points that have the same field value and are -/// connected together through their topology. Any point is considered to be connected to its Moore neighborhood: -/// 8 neighboring points for 2D and 27 neighboring points for 3D. As the name implies, ImageConnectivity only -/// works on data with a structured cell set. You will get an error if you use any other type of cell set. -/// The active field passed to the filter must be associated with the points. -/// The result of the filter is a point field of type vtkm::Id. Each entry in the point field will be a number that -/// identifies to which region it belongs. By default, this output point field is named “component”. namespace vtkm { namespace filter { -class ImageConnectivity : public vtkm::filter::FilterField + +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/connected_components/ImageConnectivity.h instead of " + "vtkm/filter/ImageConnectivity.h.") +inline void ImageConnectivity_deprecated() {} + +inline void ImageConnectivity_deprecated_warning() { -public: - using SupportedTypes = vtkm::TypeListScalarAll; + ImageConnectivity_deprecated(); +} - VTKM_CONT inline ImageConnectivity() { this->SetOutputFieldName("component"); } - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMetadata, - const vtkm::filter::PolicyBase&); +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::connected_components::ImageConnectivity.") + ImageConnectivity : public vtkm::filter::connected_components::ImageConnectivity +{ + using connected_components::ImageConnectivity::ImageConnectivity; }; + } } // namespace vtkm::filter -#include - #endif //vtk_m_filter_ImageConnectivity_h diff --git a/vtkm/filter/ImageConnectivity.hxx b/vtkm/filter/ImageConnectivity.hxx deleted file mode 100644 index 3bd094b69..000000000 --- a/vtkm/filter/ImageConnectivity.hxx +++ /dev/null @@ -1,42 +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_filter_ImageConnectivity_hxx -#define vtk_m_filter_ImageConnectivity_hxx - -namespace vtkm -{ -namespace filter -{ - -template -inline VTKM_CONT vtkm::cont::DataSet ImageConnectivity::DoExecute( - const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMetadata, - const vtkm::filter::PolicyBase& policy) -{ - if (!fieldMetadata.IsPointField()) - { - throw vtkm::cont::ErrorBadValue("Active field for ImageConnectivity must be a point field."); - } - - vtkm::cont::ArrayHandle component; - - vtkm::worklet::connectivity::ImageConnectivity().Run( - vtkm::filter::ApplyPolicyCellSet(input.GetCellSet(), policy, *this), field, component); - - auto result = CreateResult(input, component, this->GetOutputFieldName(), fieldMetadata); - return result; -} -} -} - -#endif diff --git a/vtkm/filter/MapFieldPermutation.cxx b/vtkm/filter/MapFieldPermutation.cxx index d3b042142..27efad273 100644 --- a/vtkm/filter/MapFieldPermutation.cxx +++ b/vtkm/filter/MapFieldPermutation.cxx @@ -8,65 +8,11 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include #include -#include + +#include + #include -#include - -namespace -{ - -template -struct MapPermutationWorklet : vtkm::worklet::WorkletMapField -{ - T InvalidValue; - - explicit MapPermutationWorklet(T invalidValue) - : InvalidValue(invalidValue) - { - } - - using ControlSignature = void(FieldIn permutationIndex, WholeArrayIn input, FieldOut output); - - template - VTKM_EXEC void operator()(vtkm::Id permutationIndex, - InputPortalType inputPortal, - OutputType& output) const - { - VTKM_STATIC_ASSERT(vtkm::HasVecTraits::value); - if ((permutationIndex >= 0) && (permutationIndex < inputPortal.GetNumberOfValues())) - { - output = inputPortal.Get(permutationIndex); - } - else - { - output = this->InvalidValue; - } - } -}; - -struct DoMapFieldPermutation -{ - template - void operator()(const InputArrayType& input, - const vtkm::cont::ArrayHandle& permutation, - vtkm::cont::UnknownArrayHandle& output, - vtkm::Float64 invalidValue) const - { - using BaseComponentType = typename InputArrayType::ValueType::ComponentType; - - MapPermutationWorklet worklet( - vtkm::cont::internal::CastInvalidValue(invalidValue)); - vtkm::cont::Invoker{}( - worklet, - permutation, - input, - output.ExtractArrayFromComponents(vtkm::CopyFlag::Off)); - } -}; - -} // anonymous namespace VTKM_FILTER_CORE_EXPORT VTKM_CONT bool vtkm::filter::MapFieldPermutation( const vtkm::cont::Field& inputField, @@ -76,12 +22,10 @@ VTKM_FILTER_CORE_EXPORT VTKM_CONT bool vtkm::filter::MapFieldPermutation( { VTKM_LOG_SCOPE_FUNCTION(vtkm::cont::LogLevel::Perf); - vtkm::cont::UnknownArrayHandle outputArray = inputField.GetData().NewInstanceBasic(); - outputArray.Allocate(permutation.GetNumberOfValues()); try { - inputField.GetData().CastAndCallWithExtractedArray( - DoMapFieldPermutation{}, permutation, outputArray, invalidValue); + vtkm::cont::UnknownArrayHandle outputArray = + vtkm::cont::internal::MapArrayPermutation(inputField.GetData(), permutation, invalidValue); outputField = vtkm::cont::Field(inputField.GetName(), inputField.GetAssociation(), outputArray); return true; } diff --git a/vtkm/filter/Mask.h b/vtkm/filter/Mask.h index 2eb870495..4eabdb99f 100644 --- a/vtkm/filter/Mask.h +++ b/vtkm/filter/Mask.h @@ -7,57 +7,32 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_Mask_h #define vtk_m_filter_Mask_h -#include -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Subselect cells using a stride -/// -/// Extract only every Nth cell where N is equal to a stride value -class Mask : public vtkm::filter::FilterDataSet + +VTKM_DEPRECATED(1.8, "Use vtkm/filter/entity_extraction/Mask.h instead of vtkm/filter/Mask.h.") +inline void Mask_deprecated() {} + +inline void Mask_deprecated_warning() { -public: - VTKM_CONT - Mask(); + Mask_deprecated(); +} - // When CompactPoints is set, instead of copying the points and point fields - // from the input, the filter will create new compact fields without the unused elements - VTKM_CONT - bool GetCompactPoints() const { return this->CompactPoints; } - VTKM_CONT - void SetCompactPoints(bool value) { this->CompactPoints = value; } - - // Set the stride of the subsample - VTKM_CONT - vtkm::Id GetStride() const { return this->Stride; } - VTKM_CONT - void SetStride(vtkm::Id& stride) { this->Stride = stride; } - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy); - - //Map a new field onto the resulting dataset after running the filter - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase policy); - -private: - vtkm::Id Stride; - bool CompactPoints; - vtkm::worklet::Mask Worklet; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::Mask.") Mask + : public vtkm::filter::entity_extraction::Mask +{ + using entity_extraction::Mask::Mask; }; + } } // namespace vtkm::filter -#include - -#endif // vtk_m_filter_Mask_h +#endif //vtk_m_filter_Mask_h diff --git a/vtkm/filter/NDEntropy.h b/vtkm/filter/NDEntropy.h index 37336e45e..ad0eac2e2 100644 --- a/vtkm/filter/NDEntropy.h +++ b/vtkm/filter/NDEntropy.h @@ -10,41 +10,30 @@ #ifndef vtk_m_filter_NDEntropy_h #define vtk_m_filter_NDEntropy_h -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Calculate the entropy of input N-Dims fields -/// -/// This filter calculate the entropy of input N-Dims fields. -/// -class NDEntropy : public vtkm::filter::FilterDataSet + +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/density_estimate/NDEntropy.h instead of vtkm/filter/NDEntropy.h.") +inline void NDEntropy_deprecated() {} + +inline void NDEntropy_deprecated_warning() { -public: - VTKM_CONT - NDEntropy(); + NDEntropy_deprecated(); +} - VTKM_CONT - void AddFieldAndBin(const std::string& fieldName, vtkm::Id numOfBins); - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase policy); - - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase policy); - -private: - std::vector NumOfBins; - std::vector FieldNames; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::density_estimate::NDEntropy.") NDEntropy + : public vtkm::filter::density_estimate::NDEntropy +{ + using density_estimate::NDEntropy::NDEntropy; }; + } } // namespace vtkm::filter -#include - #endif //vtk_m_filter_NDEntropy_h diff --git a/vtkm/filter/NDHistogram.h b/vtkm/filter/NDHistogram.h index 2b8cb0e45..68a0b59a2 100644 --- a/vtkm/filter/NDHistogram.h +++ b/vtkm/filter/NDHistogram.h @@ -10,61 +10,31 @@ #ifndef vtk_m_filter_NDHistogram_h #define vtk_m_filter_NDHistogram_h -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Generate a N-Dims histogram from input fields -/// -/// This filter takes a data set and with target fields and bins defined, -/// it would generate a N-Dims histogram from input fields. The result is stored -/// in a field named as "Frequency". This filed contains all the frequencies of -/// the N-Dims histogram in sparse representation. That being said, the result -/// field does not store 0 frequency bins. Meanwhile all input fields now -/// would have the same length and store bin ids instead. -/// E.g. (FieldA[i], FieldB[i], FieldC[i], Frequency[i]) is a bin in the histogram. -/// The first three numbers are binIDs for FieldA, FieldB and FieldC. Frequency[i] stores -/// the frequency for this bin (FieldA[i], FieldB[i], FieldC[i]). -/// -class NDHistogram : public vtkm::filter::FilterDataSet + +VTKM_DEPRECATED( + 1.8, + "Use vtkm/filter/density_estimate/NDHistogram.h instead of vtkm/filter/NDHistogram.h.") +inline void NDHistogram_deprecated() {} + +inline void NDHistogram_deprecated_warning() { -public: - VTKM_CONT - NDHistogram(); + NDHistogram_deprecated(); +} - VTKM_CONT - void AddFieldAndBin(const std::string& fieldName, vtkm::Id numOfBins); - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase policy); - - // This index is the field position in FieldNames - // (or the input _fieldName string vector of SetFields() Function) - VTKM_CONT - vtkm::Float64 GetBinDelta(size_t fieldIdx); - - // This index is the field position in FieldNames - // (or the input _fieldName string vector of SetFields() Function) - VTKM_CONT - vtkm::Range GetDataRange(size_t fieldIdx); - - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase policy); - -private: - std::vector NumOfBins; - std::vector FieldNames; - std::vector BinDeltas; - std::vector DataRanges; //Min Max of the field +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::density_estimate::NDHistogram.") NDHistogram + : public vtkm::filter::density_estimate::NDHistogram +{ + using density_estimate::NDHistogram::NDHistogram; }; + } } // namespace vtkm::filter -#include - #endif //vtk_m_filter_NDHistogram_h diff --git a/vtkm/filter/NewFilter.h b/vtkm/filter/NewFilter.h index 7aca9ee8c..7589accb1 100644 --- a/vtkm/filter/NewFilter.h +++ b/vtkm/filter/NewFilter.h @@ -322,15 +322,14 @@ protected: this->MapFieldsOntoOutput(input, output, defaultMapper); } -private: - VTKM_CONT - virtual vtkm::Id DetermineNumberOfThreads(const vtkm::cont::PartitionedDataSet& input); - - // Note: In C++, subclasses can override private methods of superclass. VTKM_CONT virtual vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData) = 0; VTKM_CONT virtual vtkm::cont::PartitionedDataSet DoExecutePartitions( const vtkm::cont::PartitionedDataSet& inData); +private: + VTKM_CONT + virtual vtkm::Id DetermineNumberOfThreads(const vtkm::cont::PartitionedDataSet& input); + static void defaultMapper(vtkm::cont::DataSet& output, const vtkm::cont::Field& field) { output.AddField(field); diff --git a/vtkm/filter/NewFilterField.h b/vtkm/filter/NewFilterField.h index 5adeaa714..ac09f6e67 100644 --- a/vtkm/filter/NewFilterField.h +++ b/vtkm/filter/NewFilterField.h @@ -142,6 +142,54 @@ protected: } } + template + VTKM_CONT void CastAndCallScalarField(const vtkm::cont::UnknownArrayHandle& fieldArray, + Functor&& functor, + Args&&... args) const + { + fieldArray + .CastAndCallForTypesWithFloatFallback( + std::forward(functor), std::forward(args)...); + } + + template + VTKM_CONT void CastAndCallScalarField(const vtkm::cont::Field& field, + Functor&& functor, + Args&&... args) const + { + this->CastAndCallScalarField( + field.GetData(), std::forward(functor), std::forward(args)...); + } + +private: + template + struct ScalarToVec + { + template + using type = vtkm::Vec; + }; + +protected: + template + VTKM_CONT void CastAndCallVecField(const vtkm::cont::UnknownArrayHandle& fieldArray, + Functor&& functor, + Args&&... args) const + { + using VecList = + vtkm::ListTransform::template type>; + fieldArray.CastAndCallForTypesWithFloatFallback( + std::forward(functor), std::forward(args)...); + } + + template + VTKM_CONT void CastAndCallVecField(const vtkm::cont::Field& field, + Functor&& functor, + Args&&... args) const + { + this->CastAndCallVecField( + field.GetData(), std::forward(functor), std::forward(args)...); + } + private: void ResizeIfNeeded(size_t index_st); diff --git a/vtkm/filter/ParticleDensityBase.h b/vtkm/filter/ParticleDensityBase.h deleted file mode 100644 index bb53944d8..000000000 --- a/vtkm/filter/ParticleDensityBase.h +++ /dev/null @@ -1,124 +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_filter_particle_density_base_h -#define vtk_m_filter_particle_density_base_h - -#include -#include - -namespace vtkm -{ -namespace filter -{ -// We only need the CoordinateSystem and scalar fields of the input dataset thus a FilterField -template -class ParticleDensityBase : public vtkm::filter::FilterDataSetWithField -{ -public: - // deposit scalar field associated with particles, e.g. mass/charge to mesh cells - using SupportedTypes = vtkm::TypeListFieldScalar; - -protected: - ParticleDensityBase(const vtkm::Id3& dimension, - const vtkm::Vec3f& origin, - const vtkm::Vec3f& spacing) - : Dimension(dimension) - , Origin(origin) - , Spacing(spacing) - , ComputeNumberDensity(false) - , DivideByVolume(true) - { - } - - ParticleDensityBase(const vtkm::Id3& dimension, const vtkm::Bounds& bounds) - : Dimension(dimension) - , Origin({ static_cast(bounds.X.Min), - static_cast(bounds.Y.Min), - static_cast(bounds.Z.Min) }) - , Spacing(vtkm::Vec3f{ static_cast(bounds.X.Length()), - static_cast(bounds.Y.Length()), - static_cast(bounds.Z.Length()) } / - Dimension) - , ComputeNumberDensity(false) - , DivideByVolume(true) - { - } - -public: - template - VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy) - { - if (this->ComputeNumberDensity) - { - return static_cast(this)->DoExecute( - input, - vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 }, input.GetNumberOfPoints()), - vtkm::filter::FieldMetadata{}, // Ignored - policy); - } - else - { - return this->FilterDataSetWithField::PrepareForExecution(input, policy); - } - } - - template - VTKM_CONT bool DoMapField(vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle&, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) - { - return false; - } - - VTKM_CONT void SetComputeNumberDensity(bool yes) { this->ComputeNumberDensity = yes; } - - VTKM_CONT bool GetComputeNumberDensity() const { return this->ComputeNumberDensity; } - - VTKM_CONT void SetDivideByVolume(bool yes) { this->DivideByVolume = yes; } - - VTKM_CONT bool GetDivideByVolume() const { return this->DivideByVolume; } - -protected: - vtkm::Id3 Dimension; // Cell dimension - vtkm::Vec3f Origin; - vtkm::Vec3f Spacing; - bool ComputeNumberDensity; - bool DivideByVolume; - -public: - // conceptually protected but CUDA needs this to be public - class DivideByVolumeWorklet : public vtkm::worklet::WorkletMapField - { - public: - using ControlSignature = void(FieldInOut field); - using ExecutionSignature = void(_1); - - VTKM_EXEC_CONT - explicit DivideByVolumeWorklet(vtkm::Float64 volume) - : Volume(volume) - { - } - - template - VTKM_EXEC void operator()(T& value) const - { - value = static_cast(value / Volume); - } - - private: - vtkm::Float64 Volume; - }; // class DivideByVolumeWorklet -}; -} -} -#endif //vtk_m_filter_particle_density_base_h diff --git a/vtkm/filter/ParticleDensityCloudInCell.h b/vtkm/filter/ParticleDensityCloudInCell.h index c03997cf3..35a93e15a 100644 --- a/vtkm/filter/ParticleDensityCloudInCell.h +++ b/vtkm/filter/ParticleDensityCloudInCell.h @@ -7,51 +7,34 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ +#ifndef vtk_m_filter_ParticleDensityCloudInCell_h +#define vtk_m_filter_ParticleDensityCloudInCell_h -#ifndef vtk_m_filter_particle_density_cic_h -#define vtk_m_filter_particle_density_cic_h - -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Estimate the density of particles using the Cloud-in-Cell method -/// This filter treats the CoordinateSystem of a DataSet as positions of particles. -/// The particles are infinitesimal in size with finite mass (or other scalar attributes -/// such as charge). The filter estimates density by imposing a regular grid as -/// specified in the constructor. It spreads the mass of each particle to its 8 nearest -/// neighboring grid points and summing the contribution of particles for each point -/// in the grid. -/// The mass of particles is established by setting the active field (using SetActiveField). -/// Note that the "mass" can actually be another quantity. For example, you could use -/// electrical charge in place of mass to compute the charge density. -/// Once the sum of the mass is computed for each grid point, the mass is divided by the -/// volume of the cell. Thus, the density will be computed as the units of the mass field -/// per the cubic units of the coordinate system. If you just want a sum of the mass in each -/// cell, turn off the DivideByVolume feature of this filter. -/// In addition, you can also simply count the number of particles in each cell by calling -/// SetComputeNumberDensity(true). -class ParticleDensityCloudInCell : public ParticleDensityBase + +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/density_estimate/ParticleDensityCloudInCell.h instead of " + "vtkm/filter/ParticleDensityCloudInCell.h.") +inline void ParticleDensityCloudInCell_deprecated() {} + +inline void ParticleDensityCloudInCell_deprecated_warning() { -public: - using Superclass = ParticleDensityBase; + ParticleDensityCloudInCell_deprecated(); +} - ParticleDensityCloudInCell(const vtkm::Id3& dimension, - const vtkm::Vec3f& origin, - const vtkm::Vec3f& spacing); - - ParticleDensityCloudInCell(const Id3& dimension, const vtkm::Bounds& bounds); - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::density_estimate::ParticleDensityCloudInCell.") + ParticleDensityCloudInCell : public vtkm::filter::density_estimate::ParticleDensityCloudInCell +{ + using density_estimate::ParticleDensityCloudInCell::ParticleDensityCloudInCell; }; -} // filter -} // vtkm -#include -#endif // vtk_m_filter_particle_density_cic_h +} +} // namespace vtkm::filter + +#endif //vtk_m_filter_ParticleDensityCloudInCell_h diff --git a/vtkm/filter/ParticleDensityNearestGridPoint.h b/vtkm/filter/ParticleDensityNearestGridPoint.h index 8841968c6..4edbd5dba 100644 --- a/vtkm/filter/ParticleDensityNearestGridPoint.h +++ b/vtkm/filter/ParticleDensityNearestGridPoint.h @@ -7,51 +7,35 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ +#ifndef vtk_m_filter_ParticleDensityNearestGridPoint_h +#define vtk_m_filter_ParticleDensityNearestGridPoint_h -#ifndef vtk_m_filter_particle_density_ngp_h -#define vtk_m_filter_particle_density_ngp_h - -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Estimate the density of particles using the Nearest Grid Point method -/// This filter treats the CoordinateSystem of a DataSet as positions of particles. -/// The particles are infinitesimal in size with finite mass (or other scalar attributes -/// such as charge). The filter estimates density by imposing a regular grid as -/// specified in the constructor and summing the mass of particles within each cell -/// in the grid. -/// The mass of particles is established by setting the active field (using SetActiveField). -/// Note that the "mass" can actually be another quantity. For example, you could use -/// electrical charge in place of mass to compute the charge density. -/// Once the sum of the mass is computed for each grid cell, the mass is divided by the -/// volume of the cell. Thus, the density will be computed as the units of the mass field -/// per the cubic units of the coordinate system. If you just want a sum of the mass in each -/// cell, turn off the DivideByVolume feature of this filter. -/// In addition, you can also simply count the number of particles in each cell by calling -/// SetComputeNumberDensity(true). -class ParticleDensityNearestGridPoint : public ParticleDensityBase + +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h instead of " + "vtkm/filter/ParticleDensityNearestGridPoint.h.") +inline void ParticleDensityNearestGridPoint_deprecated() {} + +inline void ParticleDensityNearestGridPoint_deprecated_warning() { -public: - using Superclass = ParticleDensityBase; + ParticleDensityNearestGridPoint_deprecated(); +} - ParticleDensityNearestGridPoint(const vtkm::Id3& dimension, - const vtkm::Vec3f& origin, - const vtkm::Vec3f& spacing); - - ParticleDensityNearestGridPoint(const vtkm::Id3& dimension, const vtkm::Bounds& bounds); - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::density_estimate::ParticleDensityNearestGridPoint.") + ParticleDensityNearestGridPoint + : public vtkm::filter::density_estimate::ParticleDensityNearestGridPoint +{ + using density_estimate::ParticleDensityNearestGridPoint::ParticleDensityNearestGridPoint; }; -} -} -#include +} +} // namespace vtkm::filter -#endif //vtk_m_filter_particle_density_ngp_h +#endif //vtk_m_filter_ParticleDensityNearestGridPoint_h diff --git a/vtkm/filter/Threshold.cxx b/vtkm/filter/Threshold.cxx deleted file mode 100644 index 7e9bef692..000000000 --- a/vtkm/filter/Threshold.cxx +++ /dev/null @@ -1,41 +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. -//============================================================================ -#define vtkm_filter_Threshold_cxx -#include - -#include - -namespace vtkm -{ -namespace filter -{ - -bool Threshold::MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field) -{ - if (field.IsFieldPoint() || field.IsFieldGlobal()) - { - //we copy the input handle to the result dataset, reusing the metadata - result.AddField(field); - return true; - } - else if (field.IsFieldCell()) - { - return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result); - } - else - { - return false; - } -} - -//----------------------------------------------------------------------------- -VTKM_FILTER_COMMON_INSTANTIATE_EXECUTE_METHOD(Threshold); -} -} diff --git a/vtkm/filter/Threshold.h b/vtkm/filter/Threshold.h index 25462d2e7..2c544733f 100644 --- a/vtkm/filter/Threshold.h +++ b/vtkm/filter/Threshold.h @@ -7,84 +7,33 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - #ifndef vtk_m_filter_Threshold_h #define vtk_m_filter_Threshold_h -#include - -#include -#include +#include +#include namespace vtkm { namespace filter { -/// \brief Extracts cells where scalar value in cell satisfies threshold criterion -/// -/// Extracts all cells from any dataset type that -/// satisfy a threshold criterion. A cell satisfies the criterion if the -/// scalar value of every point or cell satisfies the criterion. The -/// criterion takes the form of between two values. The output of this -/// filter is an permutation of the input dataset. -/// -/// You can threshold either on point or cell fields -class VTKM_FILTER_COMMON_EXPORT Threshold : public vtkm::filter::FilterDataSetWithField +VTKM_DEPRECATED(1.8, + "Use vtkm/filter/entity_extraction/Threshold.h instead of vtkm/filter/Threshold.h.") +inline void Threshold_deprecated() {} + +inline void Threshold_deprecated_warning() { -public: - using SupportedTypes = vtkm::TypeListScalarAll; + Threshold_deprecated(); +} - VTKM_CONT - void SetLowerThreshold(vtkm::Float64 value) { this->LowerValue = value; } - VTKM_CONT - void SetUpperThreshold(vtkm::Float64 value) { this->UpperValue = value; } - - VTKM_CONT - vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; } - VTKM_CONT - vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; } - - //If using scalars from point data, all scalars for all points in a cell must - //satisfy the threshold criterion if AllScalars is set. Otherwise, just a - //single scalar value satisfying the threshold criterion will extract the cell. - VTKM_CONT - void SetAllInRange(bool value) { this->ReturnAllInRange = value; } - - VTKM_CONT - bool GetAllInRange() const { return this->ReturnAllInRange; } - - template - VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy); - - //Map a new field onto the resulting dataset after running the filter - //this call is only valid after DoExecute is called - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field); - - template - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase) - { - return this->MapFieldOntoOutput(result, field); - } - -private: - double LowerValue = 0; - double UpperValue = 0; - bool ReturnAllInRange = false; - vtkm::worklet::Threshold Worklet; +class VTKM_DEPRECATED(1.8, "Use vtkm::filter::entity_extraction::Threshold.") Threshold + : public vtkm::filter::entity_extraction::Threshold +{ + using entity_extraction::Threshold::Threshold; }; -#ifndef vtkm_filter_Threshold_cxx -VTKM_FILTER_COMMON_EXPORT_EXECUTE_METHOD(Threshold); -#endif } } // namespace vtkm::filter -#include - -#endif // vtk_m_filter_Threshold_h +#endif //vtk_m_filter_Threshold_h diff --git a/vtkm/filter/Threshold.hxx b/vtkm/filter/Threshold.hxx deleted file mode 100644 index e6c47ec8c..000000000 --- a/vtkm/filter/Threshold.hxx +++ /dev/null @@ -1,84 +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_filter_Threshold_hxx -#define vtk_m_filter_Threshold_hxx - -#include -#include -#include -#include - -namespace -{ - -class ThresholdRange -{ -public: - VTKM_CONT - ThresholdRange(const vtkm::Float64& lower, const vtkm::Float64& upper) - : Lower(lower) - , Upper(upper) - { - } - - template - VTKM_EXEC bool operator()(const T& value) const - { - - return value >= static_cast(this->Lower) && value <= static_cast(this->Upper); - } - - //Needed to work with ArrayHandleVirtual - template - VTKM_EXEC bool operator()( - const vtkm::internal::ArrayPortalValueReference& value) const - { - using T = typename PortalType::ValueType; - return value.Get() >= static_cast(this->Lower) && value.Get() <= static_cast(this->Upper); - } - -private: - vtkm::Float64 Lower; - vtkm::Float64 Upper; -}; - -} // end anon namespace - -namespace vtkm -{ -namespace filter -{ - -//----------------------------------------------------------------------------- -template -vtkm::cont::DataSet Threshold::DoExecute(const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy) -{ - //get the cells and coordinates of the dataset - const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); - - ThresholdRange predicate(this->GetLowerThreshold(), this->GetUpperThreshold()); - vtkm::cont::UnknownCellSet cellOut = - this->Worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this), - field, - fieldMeta.GetAssociation(), - predicate, - this->GetAllInRange()); - - vtkm::cont::DataSet output; - output.SetCellSet(cellOut); - output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); - return output; -} -} -} -#endif diff --git a/vtkm/filter/clean_grid/CleanGrid.cxx b/vtkm/filter/clean_grid/CleanGrid.cxx index fd9cc14b2..1dd3ebc07 100644 --- a/vtkm/filter/clean_grid/CleanGrid.cxx +++ b/vtkm/filter/clean_grid/CleanGrid.cxx @@ -26,7 +26,71 @@ struct SharedStates vtkm::worklet::RemoveDegenerateCells CellCompactor; vtkm::worklet::PointMerge PointMerger; }; +} +} +} +// New Filter Design: DoMapField is now a free function in an anonymous namespace. It should be +// considered as a convenience/extension to the lambda passed to the MapFieldsOntoOutput. +// Being a free function discourages the developer to "pass" mutable states from DoExecute phase +// to DoMapField phase via data member. However, there is nothing to prevent developer doing +// stupid thing to circumvent the protection. One example here is that the developer could +// always pass a mutable reference/pointer to the filter instance and thus pass mutable state +// across the DoExecute and DoMapField boundary. We need to explicitly discourage developer +// trying to do such a thing in the manual. +namespace +{ +bool DoMapField(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + const vtkm::filter::clean_grid::CleanGrid& self, + vtkm::filter::clean_grid::SharedStates& worklets) +{ + if (field.IsFieldPoint() && (self.GetCompactPointFields() || self.GetMergePoints())) + { + vtkm::cont::Field compactedField; + if (self.GetCompactPointFields()) + { + bool success = vtkm::filter::MapFieldPermutation( + field, worklets.PointCompactor.GetPointScatter().GetOutputToInputMap(), compactedField); + if (!success) + { + return false; + } + } + else + { + compactedField = field; + } + if (self.GetMergePoints()) + { + return vtkm::filter::MapFieldMergeAverage( + compactedField, worklets.PointMerger.GetMergeKeys(), result); + } + else + { + result.AddField(compactedField); + return true; + } + } + else if (field.IsFieldCell() && self.GetRemoveDegenerateCells()) + { + return vtkm::filter::MapFieldPermutation( + field, worklets.CellCompactor.GetValidCellIds(), result); + } + else + { + result.AddField(field); + return true; + } +} +} // anonymous namespace + +namespace vtkm +{ +namespace filter +{ +namespace clean_grid +{ //----------------------------------------------------------------------------- vtkm::cont::DataSet CleanGrid::GenerateOutput(const vtkm::cont::DataSet& inData, vtkm::cont::CellSetExplicit<>& outputCellSet, @@ -116,61 +180,6 @@ vtkm::cont::DataSet CleanGrid::GenerateOutput(const vtkm::cont::DataSet& inData, return outData; } -// New Filter Design: DoMapField is now a free function in an anonymous namespace. It should be -// considered as a convenience/extension to the lambda passed to the MapFieldsOntoOutput. -// Being a free function discourages the developer to "pass" mutable states from DoExecute phase -// to DoMapField phase via data member. However, there is nothing to prevent developer doing -// stupid thing to circumvent the protection. One example here is that the developer could -// always pass a mutable reference/pointer to the filter instance and thus pass mutable state -// across the DoExecute and DoMapField boundary. We need to explicitly discourage developer -// trying to do such a thing in the manual. -namespace -{ -bool DoMapField(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - const CleanGrid& self, - clean_grid::SharedStates& worklets) -{ - if (field.IsFieldPoint() && (self.GetCompactPointFields() || self.GetMergePoints())) - { - vtkm::cont::Field compactedField; - if (self.GetCompactPointFields()) - { - bool success = vtkm::filter::MapFieldPermutation( - field, worklets.PointCompactor.GetPointScatter().GetOutputToInputMap(), compactedField); - if (!success) - { - return false; - } - } - else - { - compactedField = field; - } - if (self.GetMergePoints()) - { - return vtkm::filter::MapFieldMergeAverage( - compactedField, worklets.PointMerger.GetMergeKeys(), result); - } - else - { - result.AddField(compactedField); - return true; - } - } - else if (field.IsFieldCell() && self.GetRemoveDegenerateCells()) - { - return vtkm::filter::MapFieldPermutation( - field, worklets.CellCompactor.GetValidCellIds(), result); - } - else - { - result.AddField(field); - return true; - } -} -} // anonymous namespace - vtkm::cont::DataSet CleanGrid::DoExecute(const vtkm::cont::DataSet& inData) { // New Filter Design: mutable states that was a data member of the filter is now a local diff --git a/vtkm/filter/clean_grid/testing/CMakeLists.txt b/vtkm/filter/clean_grid/testing/CMakeLists.txt index 2e5cf25a4..56e76b81b 100644 --- a/vtkm/filter/clean_grid/testing/CMakeLists.txt +++ b/vtkm/filter/clean_grid/testing/CMakeLists.txt @@ -18,6 +18,6 @@ set(libraries vtkm_unit_tests( SOURCES ${unit_tests} LIBRARIES ${libraries} - ALL_BACKENDS # deivce compiler needed, uses ArrayCopy +# ALL_BACKENDS # deivce compiler needed, uses ArrayCopy USE_VTKM_JOB_POOL ) diff --git a/vtkm/filter/clean_grid/worklet/RemoveUnusedPoints.h b/vtkm/filter/clean_grid/worklet/RemoveUnusedPoints.h index 79562fbeb..4a63990ae 100644 --- a/vtkm/filter/clean_grid/worklet/RemoveUnusedPoints.h +++ b/vtkm/filter/clean_grid/worklet/RemoveUnusedPoints.h @@ -10,7 +10,7 @@ #ifndef vtk_m_worklet_RemoveUnusedPoints_h #define vtk_m_worklet_RemoveUnusedPoints_h -#include +#include #include #include #include @@ -102,9 +102,7 @@ public: if (this->MaskArray.GetNumberOfValues() < 1) { // Initialize mask array to 0. - vtkm::cont::ArrayCopy( - vtkm::cont::ArrayHandleConstant(0, inCellSet.GetNumberOfPoints()), - this->MaskArray); + this->MaskArray.AllocateAndFill(inCellSet.GetNumberOfPoints(), 0); } VTKM_ASSERT(this->MaskArray.GetNumberOfValues() == inCellSet.GetNumberOfPoints()); @@ -257,7 +255,7 @@ public: VTKM_CONT void MapPointFieldDeep(const vtkm::cont::ArrayHandle& inArray, vtkm::cont::ArrayHandle& outArray) const { - vtkm::cont::ArrayCopy(this->MapPointFieldShallow(inArray), outArray); + vtkm::cont::ArrayCopyDevice(this->MapPointFieldShallow(inArray), outArray); } template diff --git a/vtkm/filter/connected_components/CMakeLists.txt b/vtkm/filter/connected_components/CMakeLists.txt new file mode 100644 index 000000000..0d56b1766 --- /dev/null +++ b/vtkm/filter/connected_components/CMakeLists.txt @@ -0,0 +1,34 @@ +##============================================================================ +## 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. +##============================================================================ +set(connected_components_headers + CellSetConnectivity.h + ImageConnectivity.h + ) +set(connected_components_sources_device + CellSetConnectivity.cxx + ImageConnectivity.cxx + ) + +vtkm_library( + NAME vtkm_filter_connected_components + HEADERS ${connected_components_headers} + DEVICE_SOURCES ${connected_components_sources_device} + USE_VTKM_JOB_POOL +) + +target_link_libraries(vtkm_filter_connected_components PRIVATE vtkm_worklet PUBLIC vtkm_filter_core) +target_link_libraries(vtkm_filter PUBLIC INTERFACE vtkm_filter_connected_components) + +add_subdirectory(worklet) + +#-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - +if (VTKm_ENABLE_TESTING) + add_subdirectory(testing) +endif () diff --git a/vtkm/filter/connected_components/CellSetConnectivity.cxx b/vtkm/filter/connected_components/CellSetConnectivity.cxx new file mode 100644 index 000000000..0b7e02b14 --- /dev/null +++ b/vtkm/filter/connected_components/CellSetConnectivity.cxx @@ -0,0 +1,34 @@ +//============================================================================ +// 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 vtkm +{ +namespace filter +{ +namespace connected_components +{ +VTKM_CONT vtkm::cont::DataSet CellSetConnectivity::DoExecute(const vtkm::cont::DataSet& input) +{ + vtkm::cont::ArrayHandle component; + + vtkm::worklet::connectivity::CellSetConnectivity().Run(input.GetCellSet(), component); + + auto output = CreateResultFieldCell(input, component, this->GetOutputFieldName()); + this->MapFieldsOntoOutput(input, output); + + return output; +} +} // namespace connected_components +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/connected_components/CellSetConnectivity.h b/vtkm/filter/connected_components/CellSetConnectivity.h new file mode 100644 index 000000000..a41c5d748 --- /dev/null +++ b/vtkm/filter/connected_components/CellSetConnectivity.h @@ -0,0 +1,46 @@ +//============================================================================ +// 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_filter_connected_components_CellSetConnectivity_h +#define vtk_m_filter_connected_components_CellSetConnectivity_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace connected_components +{ +/// \brief Finds groups of cells that are connected together through their topology. +/// +/// Finds and labels groups of cells that are connected together through their topology. +/// Two cells are considered connected if they share an edge. CellSetConnectivity identifies some +/// number of components and assigns each component a unique integer. +/// The result of the filter is a cell field of type vtkm::Id with the default name of 'component'. +/// Each entry in the cell field will be a number that identifies to which component the cell belongs. +class VTKM_FILTER_CONNECTED_COMPONENTS_EXPORT CellSetConnectivity + : public vtkm::filter::NewFilterField +{ +public: + VTKM_CONT CellSetConnectivity() { this->SetOutputFieldName("component"); } + +private: + VTKM_CONT + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + std::string OutputFieldName; +}; +} +} +} + +#endif //vtk_m_filter_connected_components_CellSetConnectivity_h diff --git a/vtkm/filter/connected_components/ImageConnectivity.cxx b/vtkm/filter/connected_components/ImageConnectivity.cxx new file mode 100644 index 000000000..23a8674f5 --- /dev/null +++ b/vtkm/filter/connected_components/ImageConnectivity.cxx @@ -0,0 +1,45 @@ +//============================================================================ +// 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 vtkm +{ +namespace filter +{ +namespace connected_components +{ +VTKM_CONT vtkm::cont::DataSet ImageConnectivity::DoExecute(const vtkm::cont::DataSet& input) +{ + const auto& field = this->GetFieldFromDataSet(input); + + if (!field.IsFieldPoint()) + { + throw vtkm::cont::ErrorBadValue("Active field for ImageConnectivity must be a point field."); + } + + vtkm::cont::ArrayHandle component; + + auto resolveType = [&](const auto& concrete) { + vtkm::worklet::connectivity::ImageConnectivity().Run(input.GetCellSet(), concrete, component); + }; + const auto& fieldArray = field.GetData(); + this->CastAndCallScalarField(fieldArray, resolveType); + + auto output = CreateResultFieldPoint(input, component, this->GetOutputFieldName()); + this->MapFieldsOntoOutput(input, output); + + return output; +} +} // namespace connected_components +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/connected_components/ImageConnectivity.h b/vtkm/filter/connected_components/ImageConnectivity.h new file mode 100644 index 000000000..e66bc6b3e --- /dev/null +++ b/vtkm/filter/connected_components/ImageConnectivity.h @@ -0,0 +1,47 @@ +//============================================================================ +// 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_filter_connected_components_ImageConnectivity_h +#define vtk_m_filter_connected_components_ImageConnectivity_h + +#include +#include + +/// \brief Groups connected points that have the same field value +/// +/// +/// The ImageConnectivity filter finds groups of points that have the same field value and are +/// connected together through their topology. Any point is considered to be connected to its Moore neighborhood: +/// 8 neighboring points for 2D and 27 neighboring points for 3D. As the name implies, ImageConnectivity only +/// works on data with a structured cell set. You will get an error if you use any other type of cell set. +/// The active field passed to the filter must be associated with the points. +/// The result of the filter is a point field of type vtkm::Id. Each entry in the point field will be a number that +/// identifies to which region it belongs. By default, this output point field is named “component”. +namespace vtkm +{ +namespace filter +{ +namespace connected_components +{ +class VTKM_FILTER_CONNECTED_COMPONENTS_EXPORT ImageConnectivity + : public vtkm::filter::NewFilterField +{ +public: + VTKM_CONT ImageConnectivity() { this->SetOutputFieldName("component"); } + +private: + VTKM_CONT + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; +}; +} // namespace connected_components +} // namespace filter +} // namespace vtkm + +#endif //vtk_m_filter_connected_components_ImageConnectivity_h diff --git a/vtkm/filter/connected_components/testing/CMakeLists.txt b/vtkm/filter/connected_components/testing/CMakeLists.txt new file mode 100644 index 000000000..bf71afc7f --- /dev/null +++ b/vtkm/filter/connected_components/testing/CMakeLists.txt @@ -0,0 +1,27 @@ +##============================================================================ +## 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. +##============================================================================ + +set(unit_tests + UnitTestCellSetConnectivityFilter.cxx + UnitTestImageConnectivityFilter.cxx + ) + +set(libraries + vtkm_filter_contour + vtkm_filter_connected_components + vtkm_source + ) + +vtkm_unit_tests( + SOURCES ${unit_tests} + LIBRARIES ${libraries} + ALL_BACKENDS # uses vtkm::cont::Algorithm + USE_VTKM_JOB_POOL +) diff --git a/vtkm/filter/testing/UnitTestCellSetConnectivityFilter.cxx b/vtkm/filter/connected_components/testing/UnitTestCellSetConnectivityFilter.cxx similarity index 90% rename from vtkm/filter/testing/UnitTestCellSetConnectivityFilter.cxx rename to vtkm/filter/connected_components/testing/UnitTestCellSetConnectivityFilter.cxx index 3afd8165c..9abd60cbf 100644 --- a/vtkm/filter/testing/UnitTestCellSetConnectivityFilter.cxx +++ b/vtkm/filter/connected_components/testing/UnitTestCellSetConnectivityFilter.cxx @@ -8,11 +8,12 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include -#include +#include #include + #include namespace @@ -34,7 +35,7 @@ public: filter.SetActiveField("tangle"); vtkm::cont::DataSet iso = filter.Execute(dataSet); - vtkm::filter::CellSetConnectivity connectivity; + vtkm::filter::connected_components::CellSetConnectivity connectivity; const vtkm::cont::DataSet output = connectivity.Execute(iso); vtkm::cont::ArrayHandle componentArray; @@ -52,7 +53,7 @@ public: { vtkm::cont::DataSet dataSet = vtkm::cont::testing::MakeTestDataSet().Make3DExplicitDataSet5(); - vtkm::filter::CellSetConnectivity connectivity; + vtkm::filter::connected_components::CellSetConnectivity connectivity; const vtkm::cont::DataSet output = connectivity.Execute(dataSet); vtkm::cont::ArrayHandle componentArray; @@ -69,7 +70,7 @@ public: void TestUniformDataSet() const { vtkm::cont::DataSet dataSet = vtkm::cont::testing::MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::CellSetConnectivity connectivity; + vtkm::filter::connected_components::CellSetConnectivity connectivity; const vtkm::cont::DataSet output = connectivity.Execute(dataSet); vtkm::cont::ArrayHandle componentArray; diff --git a/vtkm/filter/testing/UnitTestImageConnectivityFilter.cxx b/vtkm/filter/connected_components/testing/UnitTestImageConnectivityFilter.cxx similarity index 94% rename from vtkm/filter/testing/UnitTestImageConnectivityFilter.cxx rename to vtkm/filter/connected_components/testing/UnitTestImageConnectivityFilter.cxx index a2113b579..6c2cf4153 100644 --- a/vtkm/filter/testing/UnitTestImageConnectivityFilter.cxx +++ b/vtkm/filter/connected_components/testing/UnitTestImageConnectivityFilter.cxx @@ -8,7 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include @@ -39,7 +39,7 @@ void TestImageConnectivity() { vtkm::cont::DataSet dataSet = MakeTestDataSet(); - vtkm::filter::ImageConnectivity connectivity; + vtkm::filter::connected_components::ImageConnectivity connectivity; connectivity.SetActiveField("color"); const vtkm::cont::DataSet outputData = connectivity.Execute(dataSet); diff --git a/vtkm/worklet/connectivities/CMakeLists.txt b/vtkm/filter/connected_components/worklet/CMakeLists.txt similarity index 100% rename from vtkm/worklet/connectivities/CMakeLists.txt rename to vtkm/filter/connected_components/worklet/CMakeLists.txt diff --git a/vtkm/worklet/connectivities/CellSetConnectivity.h b/vtkm/filter/connected_components/worklet/CellSetConnectivity.h similarity index 90% rename from vtkm/worklet/connectivities/CellSetConnectivity.h rename to vtkm/filter/connected_components/worklet/CellSetConnectivity.h index 25fa10279..f97dc15b4 100644 --- a/vtkm/worklet/connectivities/CellSetConnectivity.h +++ b/vtkm/filter/connected_components/worklet/CellSetConnectivity.h @@ -10,8 +10,8 @@ #ifndef vtk_m_worklet_connectivity_CellSetConnectivity_h #define vtk_m_worklet_connectivity_CellSetConnectivity_h -#include -#include +#include +#include namespace vtkm { diff --git a/vtkm/worklet/connectivities/CellSetDualGraph.h b/vtkm/filter/connected_components/worklet/CellSetDualGraph.h similarity index 100% rename from vtkm/worklet/connectivities/CellSetDualGraph.h rename to vtkm/filter/connected_components/worklet/CellSetDualGraph.h diff --git a/vtkm/worklet/connectivities/GraphConnectivity.h b/vtkm/filter/connected_components/worklet/GraphConnectivity.h similarity index 94% rename from vtkm/worklet/connectivities/GraphConnectivity.h rename to vtkm/filter/connected_components/worklet/GraphConnectivity.h index cda31610d..0e676d154 100644 --- a/vtkm/worklet/connectivities/GraphConnectivity.h +++ b/vtkm/filter/connected_components/worklet/GraphConnectivity.h @@ -12,9 +12,9 @@ #define vtk_m_worklet_connectivity_graph_connectivity_h #include -#include -#include -#include +#include +#include +#include namespace vtkm { diff --git a/vtkm/worklet/connectivities/ImageConnectivity.h b/vtkm/filter/connected_components/worklet/ImageConnectivity.h similarity index 94% rename from vtkm/worklet/connectivities/ImageConnectivity.h rename to vtkm/filter/connected_components/worklet/ImageConnectivity.h index 455bbd00e..8d7a34660 100644 --- a/vtkm/worklet/connectivities/ImageConnectivity.h +++ b/vtkm/filter/connected_components/worklet/ImageConnectivity.h @@ -11,14 +11,15 @@ #ifndef vtk_m_worklet_connectivity_ImageConnectivity_h #define vtk_m_worklet_connectivity_ImageConnectivity_h +#include #include #include #include #include #include -#include -#include +#include +#include namespace vtkm @@ -41,7 +42,7 @@ public: using ExecutionSignature = void(Boundary, _2, _3, _4); - // compOut is a "linear" alias of neightborComp such that we can update component labels + // compOut is a "linear" alias of neighborComp such that we can update component labels template #include +#include #include #include diff --git a/vtkm/filter/density_estimate/CMakeLists.txt b/vtkm/filter/density_estimate/CMakeLists.txt new file mode 100644 index 000000000..05209da58 --- /dev/null +++ b/vtkm/filter/density_estimate/CMakeLists.txt @@ -0,0 +1,50 @@ +##============================================================================ +## 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. +##============================================================================ +set(density_estimate_headers + Entropy.h + Histogram.h + NDEntropy.h + NDHistogram.h + ParticleDensityBase.h + ParticleDensityCloudInCell.h + ParticleDensityNearestGridPoint.h + ) + +set(density_estimate_sources_device + Entropy.cxx + Histogram.cxx + NDEntropy.cxx + NDHistogram.cxx + ParticleDensityBase.cxx + ParticleDensityCloudInCell.cxx + ParticleDensityNearestGridPoint.cxx + ) + +vtkm_library( + NAME vtkm_filter_density_estimate + HEADERS ${density_estimate_headers} + DEVICE_SOURCES ${density_estimate_sources_device} + USE_VTKM_JOB_POOL +) + +set_property(TARGET + vtkm_filter_density_estimate + PROPERTY UNITY_BUILD_MODE GROUP + ) + +target_link_libraries(vtkm_filter_density_estimate PRIVATE vtkm_worklet PUBLIC vtkm_filter_core) +target_link_libraries(vtkm_filter PUBLIC INTERFACE vtkm_filter_density_estimate) + +add_subdirectory(worklet) + +#-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - +if (VTKm_ENABLE_TESTING) + add_subdirectory(testing) +endif () diff --git a/vtkm/filter/density_estimate/Entropy.cxx b/vtkm/filter/density_estimate/Entropy.cxx new file mode 100644 index 000000000..c87a3ece0 --- /dev/null +++ b/vtkm/filter/density_estimate/Entropy.cxx @@ -0,0 +1,53 @@ +//============================================================================ +// 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 vtkm +{ +namespace filter +{ +namespace density_estimate +{ +//----------------------------------------------------------------------------- +VTKM_CONT Entropy::Entropy() + +{ + this->SetOutputFieldName("entropy"); +} + +//----------------------------------------------------------------------------- +VTKM_CONT vtkm::cont::DataSet Entropy::DoExecute(const vtkm::cont::DataSet& inDataSet) +{ + vtkm::worklet::FieldEntropy worklet; + + vtkm::Float64 e = 0; + auto resolveType = [&](const auto& concrete) { e = worklet.Run(concrete, this->NumberOfBins); }; + const auto& fieldArray = this->GetFieldFromDataSet(inDataSet).GetData(); + fieldArray + .CastAndCallForTypesWithFloatFallback( + resolveType); + + //the entropy vector only contain one element, the entropy of the input field + vtkm::cont::ArrayHandle entropy; + entropy.Allocate(1); + entropy.WritePortal().Set(0, e); + + vtkm::cont::DataSet output; + output.AddField( + { this->GetOutputFieldName(), vtkm::cont::Field::Association::WHOLE_MESH, entropy }); + + // The output is a "summary" of the input, no need to map fields + return output; +} +} // namespace density_estimate +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/density_estimate/Entropy.h b/vtkm/filter/density_estimate/Entropy.h new file mode 100644 index 000000000..e820ab50a --- /dev/null +++ b/vtkm/filter/density_estimate/Entropy.h @@ -0,0 +1,51 @@ +//============================================================================ +// 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_filter_density_estimate_Entropy_h +#define vtk_m_filter_density_estimate_Entropy_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ +/// \brief Construct the entropy histogram of a given Field +/// +/// Construct a histogram which is used to compute the entropy with a default of 10 bins +/// +class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT Entropy : public vtkm::filter::NewFilterField +{ +public: + //currently the Entropy filter only works on scalar data. + using SupportedTypes = TypeListScalarAll; + + //Construct a histogram which is used to compute the entropy with a default of 10 bins + VTKM_CONT + Entropy(); + + VTKM_CONT + void SetNumberOfBins(vtkm::Id count) { this->NumberOfBins = count; } + VTKM_CONT + vtkm::Id GetNumberOfBins() const { return this->NumberOfBins; } + +private: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + vtkm::Id NumberOfBins = 10; +}; +} // namespace density_estimate +} // namespace filter +} // namespace vtkm + +#endif // vtk_m_filter_density_estimate_Entropy_h diff --git a/vtkm/filter/Histogram.hxx b/vtkm/filter/density_estimate/Histogram.cxx similarity index 77% rename from vtkm/filter/Histogram.hxx rename to vtkm/filter/density_estimate/Histogram.cxx index 20bf1f76d..b00679612 100644 --- a/vtkm/filter/Histogram.hxx +++ b/vtkm/filter/density_estimate/Histogram.cxx @@ -8,13 +8,10 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_Histogram_hxx -#define vtk_m_filter_Histogram_hxx - -#include +#include +#include #include -#include #include #include #include @@ -27,6 +24,8 @@ namespace vtkm { namespace filter { +namespace density_estimate +{ namespace detail { class DistributedHistogram @@ -165,53 +164,61 @@ private: } // namespace detail //----------------------------------------------------------------------------- -inline VTKM_CONT Histogram::Histogram() - : NumberOfBins(10) - , BinDelta(0) - , ComputedRange() - , Range() +VTKM_CONT Histogram::Histogram() { this->SetOutputFieldName("histogram"); } -//----------------------------------------------------------------------------- -template -inline VTKM_CONT vtkm::cont::DataSet Histogram::DoExecute( - const vtkm::cont::DataSet&, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) +VTKM_CONT vtkm::cont::DataSet Histogram::DoExecute(const vtkm::cont::DataSet& input) { vtkm::cont::ArrayHandle binArray; - T delta; - vtkm::worklet::FieldHistogram worklet; - if (this->ComputedRange.IsNonEmpty()) - { - worklet.Run(field, - this->NumberOfBins, - static_cast(this->ComputedRange.Min), - static_cast(this->ComputedRange.Max), - delta, - binArray); - } - else - { - worklet.Run(field, this->NumberOfBins, this->ComputedRange, delta, binArray); - } + auto resolveType = [&](const auto& concrete) { + using T = typename std::decay_t::ValueType; + T delta; + + vtkm::worklet::FieldHistogram worklet; + if (this->ComputedRange.IsNonEmpty()) + { + worklet.Run(concrete, + this->NumberOfBins, + static_cast(this->ComputedRange.Min), + static_cast(this->ComputedRange.Max), + delta, + binArray); + } + else + { + worklet.Run(concrete, this->NumberOfBins, this->ComputedRange, delta, binArray); + } + + this->BinDelta = static_cast(delta); + }; + + const auto& fieldArray = this->GetFieldFromDataSet(input).GetData(); + fieldArray + .CastAndCallForTypesWithFloatFallback( + resolveType); - this->BinDelta = static_cast(delta); vtkm::cont::DataSet output; - vtkm::cont::Field rfield( - this->GetOutputFieldName(), vtkm::cont::Field::Association::WHOLE_MESH, binArray); - output.AddField(rfield); + output.AddField( + { this->GetOutputFieldName(), vtkm::cont::Field::Association::WHOLE_MESH, binArray }); + + // The output is a "summary" of the input, no need to map fields return output; } +VTKM_CONT vtkm::cont::PartitionedDataSet Histogram::DoExecutePartitions( + const vtkm::cont::PartitionedDataSet& input) +{ + this->PreExecute(input); + auto result = this->NewFilter::DoExecutePartitions(input); + this->PostExecute(input, result); + return result; +} + //----------------------------------------------------------------------------- -template -inline VTKM_CONT void Histogram::PreExecute(const vtkm::cont::PartitionedDataSet& input, - const vtkm::filter::PolicyBase&) +VTKM_CONT void Histogram::PreExecute(const vtkm::cont::PartitionedDataSet& input) { if (this->Range.IsNonEmpty()) { @@ -230,10 +237,8 @@ inline VTKM_CONT void Histogram::PreExecute(const vtkm::cont::PartitionedDataSet } //----------------------------------------------------------------------------- -template -inline VTKM_CONT void Histogram::PostExecute(const vtkm::cont::PartitionedDataSet&, - vtkm::cont::PartitionedDataSet& result, - const vtkm::filter::PolicyBase&) +VTKM_CONT void Histogram::PostExecute(const vtkm::cont::PartitionedDataSet&, + vtkm::cont::PartitionedDataSet& result) { // iterate and compute histogram for each local block. detail::DistributedHistogram helper(result.GetNumberOfPartitions()); @@ -250,7 +255,6 @@ inline VTKM_CONT void Histogram::PostExecute(const vtkm::cont::PartitionedDataSe result = vtkm::cont::PartitionedDataSet(output); } -} -} // namespace vtkm::filter - -#endif +} // namespace density_estimate +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/density_estimate/Histogram.h b/vtkm/filter/density_estimate/Histogram.h new file mode 100644 index 000000000..1600a80a6 --- /dev/null +++ b/vtkm/filter/density_estimate/Histogram.h @@ -0,0 +1,84 @@ +//============================================================================ +// 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_filter_density_estimate_Histogram_h +#define vtk_m_filter_density_estimate_Histogram_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ +/// \brief Construct the histogram of a given Field +/// +/// Construct a histogram with a default of 10 bins. +/// +class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT Histogram : public vtkm::filter::NewFilterField +{ +public: + //Construct a histogram with a default of 10 bins + VTKM_CONT + Histogram(); + + VTKM_CONT + void SetNumberOfBins(vtkm::Id count) { this->NumberOfBins = count; } + + VTKM_CONT + vtkm::Id GetNumberOfBins() const { return this->NumberOfBins; } + + //@{ + /// Get/Set the range to use to generate the histogram. If range is set to + /// empty, the field's global range (computed using `vtkm::cont::FieldRangeGlobalCompute`) + /// will be used. + VTKM_CONT + void SetRange(const vtkm::Range& range) { this->Range = range; } + + VTKM_CONT + const vtkm::Range& GetRange() const { return this->Range; } + //@} + + /// Returns the bin delta of the last computed field. + VTKM_CONT + vtkm::Float64 GetBinDelta() const { return this->BinDelta; } + + /// Returns the range used for most recent execute. If `SetRange` is used to + /// specify and non-empty range, then this will be same as the range after + /// the `Execute` call. + VTKM_CONT + vtkm::Range GetComputedRange() const { return this->ComputedRange; } + +private: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + VTKM_CONT vtkm::cont::PartitionedDataSet DoExecutePartitions( + const vtkm::cont::PartitionedDataSet& inData) override; + + //@{ + /// when operating on vtkm::cont::PartitionedDataSet, we + /// want to do processing across ranks as well. Just adding pre/post handles + /// for the same does the trick. + VTKM_CONT void PreExecute(const vtkm::cont::PartitionedDataSet& input); + VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input, + vtkm::cont::PartitionedDataSet& output); + //@} + + vtkm::Id NumberOfBins = 10; + vtkm::Float64 BinDelta = 0; + vtkm::Range ComputedRange; + vtkm::Range Range; +}; +} // namespace density_estimate +} // namespace filter +} // namespace vtkm + +#endif // vtk_m_filter_density_estimate_Histogram_h diff --git a/vtkm/filter/NDEntropy.hxx b/vtkm/filter/density_estimate/NDEntropy.cxx similarity index 61% rename from vtkm/filter/NDEntropy.hxx rename to vtkm/filter/density_estimate/NDEntropy.cxx index 7c920b0e3..ebb5f53cd 100644 --- a/vtkm/filter/NDEntropy.hxx +++ b/vtkm/filter/density_estimate/NDEntropy.cxx @@ -7,29 +7,22 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_NDEntropy_hxx -#define vtk_m_filter_NDEntropy_hxx - -#include -#include +#include +#include namespace vtkm { namespace filter { - -inline VTKM_CONT NDEntropy::NDEntropy() {} - +namespace density_estimate +{ void NDEntropy::AddFieldAndBin(const std::string& fieldName, vtkm::Id numOfBins) { this->FieldNames.push_back(fieldName); this->NumOfBins.push_back(numOfBins); } -template -inline VTKM_CONT vtkm::cont::DataSet NDEntropy::DoExecute( - const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase vtkmNotUsed(policy)) +VTKM_CONT vtkm::cont::DataSet NDEntropy::DoExecute(const vtkm::cont::DataSet& inData) { vtkm::worklet::NDimsEntropy ndEntropy; ndEntropy.SetNumOfDataPoints(inData.GetField(0).GetNumberOfValues()); @@ -48,20 +41,11 @@ inline VTKM_CONT vtkm::cont::DataSet NDEntropy::DoExecute( entropyHandle.Allocate(1); entropyHandle.WritePortal().Set(0, entropy); - vtkm::cont::DataSet outputData; - outputData.AddField(vtkm::cont::make_FieldPoint("Entropy", entropyHandle)); + outputData.AddField({ "Entropy", vtkm::cont::Field::Association::WHOLE_MESH, entropyHandle }); + // The output is a "summary" of the input, no need to map fields return outputData; } - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool NDEntropy::MapFieldOntoOutput(vtkm::cont::DataSet&, - const vtkm::cont::Field&, - vtkm::filter::PolicyBase) -{ - return false; -} -} -} -#endif +} // namespace density_estimate +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/density_estimate/NDEntropy.h b/vtkm/filter/density_estimate/NDEntropy.h new file mode 100644 index 000000000..6cfcd5f13 --- /dev/null +++ b/vtkm/filter/density_estimate/NDEntropy.h @@ -0,0 +1,42 @@ +//============================================================================ +// 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_filter_density_estimate_NDEntropy_h +#define vtk_m_filter_density_estimate_NDEntropy_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ +/// \brief Calculate the entropy of input N-Dims fields +/// +/// This filter calculate the entropy of input N-Dims fields. +/// +class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT NDEntropy : public vtkm::filter::NewFilterField +{ +public: + VTKM_CONT + void AddFieldAndBin(const std::string& fieldName, vtkm::Id numOfBins); + +private: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + std::vector NumOfBins; + std::vector FieldNames; +}; +} +} +} // namespace vtkm::filter + +#endif //vtk_m_filter_density_estimate_NDEntropy_h diff --git a/vtkm/filter/NDHistogram.hxx b/vtkm/filter/density_estimate/NDHistogram.cxx similarity index 58% rename from vtkm/filter/NDHistogram.hxx rename to vtkm/filter/density_estimate/NDHistogram.cxx index f054f359f..65a35d5a5 100644 --- a/vtkm/filter/NDHistogram.hxx +++ b/vtkm/filter/density_estimate/NDHistogram.cxx @@ -7,20 +7,17 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_NDHistogram_hxx -#define vtk_m_filter_NDHistogram_hxx - #include -#include -#include + +#include +#include namespace vtkm { namespace filter { - -inline VTKM_CONT NDHistogram::NDHistogram() {} - +namespace density_estimate +{ void NDHistogram::AddFieldAndBin(const std::string& fieldName, vtkm::Id numOfBins) { this->FieldNames.push_back(fieldName); @@ -37,9 +34,7 @@ vtkm::Range NDHistogram::GetDataRange(size_t fieldIdx) return DataRanges[fieldIdx]; } -template -inline VTKM_CONT vtkm::cont::DataSet NDHistogram::DoExecute(const vtkm::cont::DataSet& inData, - vtkm::filter::PolicyBase policy) +VTKM_CONT vtkm::cont::DataSet NDHistogram::DoExecute(const vtkm::cont::DataSet& inData) { vtkm::worklet::NDimsHistogram ndHistogram; @@ -53,10 +48,7 @@ inline VTKM_CONT vtkm::cont::DataSet NDHistogram::DoExecute(const vtkm::cont::Da vtkm::Range rangeField; vtkm::Float64 deltaField; ndHistogram.AddField( - vtkm::filter::ApplyPolicyFieldNotActive(inData.GetField(this->FieldNames[i]), policy), - this->NumOfBins[i], - rangeField, - deltaField); + inData.GetField(this->FieldNames[i]).GetData(), this->NumOfBins[i], rangeField, deltaField); DataRanges.push_back(rangeField); BinDeltas.push_back(deltaField); } @@ -68,21 +60,14 @@ inline VTKM_CONT vtkm::cont::DataSet NDHistogram::DoExecute(const vtkm::cont::Da vtkm::cont::DataSet outputData; for (size_t i = 0; i < binIds.size(); i++) { - outputData.AddField(vtkm::cont::make_FieldPoint(this->FieldNames[i], binIds[i])); + outputData.AddField( + { this->FieldNames[i], vtkm::cont::Field::Association::WHOLE_MESH, binIds[i] }); } - outputData.AddField(vtkm::cont::make_FieldPoint("Frequency", freqs)); - + outputData.AddField({ "Frequency", vtkm::cont::Field::Association::WHOLE_MESH, freqs }); + // The output is a "summary" of the input, no need to map fields return outputData; } -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool NDHistogram::MapFieldOntoOutput(vtkm::cont::DataSet&, - const vtkm::cont::Field&, - vtkm::filter::PolicyBase) -{ - return false; -} -} -} -#endif +} // namespace density_estimate +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/density_estimate/NDHistogram.h b/vtkm/filter/density_estimate/NDHistogram.h new file mode 100644 index 000000000..2a4cbeff5 --- /dev/null +++ b/vtkm/filter/density_estimate/NDHistogram.h @@ -0,0 +1,62 @@ +//============================================================================ +// 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_filter_density_estimate_NDHistogram_h +#define vtk_m_filter_density_estimate_NDHistogram_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ +/// \brief Generate a N-Dims histogram from input fields +/// +/// This filter takes a data set and with target fields and bins defined, +/// it would generate a N-Dims histogram from input fields. The result is stored +/// in a field named as "Frequency". This filed contains all the frequencies of +/// the N-Dims histogram in sparse representation. That being said, the result +/// field does not store 0 frequency bins. Meanwhile all input fields now +/// would have the same length and store bin ids instead. +/// E.g. (FieldA[i], FieldB[i], FieldC[i], Frequency[i]) is a bin in the histogram. +/// The first three numbers are binIDs for FieldA, FieldB and FieldC. Frequency[i] stores +/// the frequency for this bin (FieldA[i], FieldB[i], FieldC[i]). +/// +class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT NDHistogram : public vtkm::filter::NewFilterField +{ +public: + VTKM_CONT + void AddFieldAndBin(const std::string& fieldName, vtkm::Id numOfBins); + + // This index is the field position in FieldNames + // (or the input _fieldName string vector of SetFields() Function) + VTKM_CONT + vtkm::Float64 GetBinDelta(size_t fieldIdx); + + // This index is the field position in FieldNames + // (or the input _fieldName string vector of SetFields() Function) + VTKM_CONT + vtkm::Range GetDataRange(size_t fieldIdx); + +private: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + std::vector NumOfBins; + std::vector FieldNames; + std::vector BinDeltas; + std::vector DataRanges; //Min Max of the field +}; +} // namespace density_estimate +} // namespace filter +} // namespace vtm + +#endif //vtk_m_filter_density_estimate_NDHistogram_h diff --git a/vtkm/filter/density_estimate/ParticleDensityBase.cxx b/vtkm/filter/density_estimate/ParticleDensityBase.cxx new file mode 100644 index 000000000..b91c538a6 --- /dev/null +++ b/vtkm/filter/density_estimate/ParticleDensityBase.cxx @@ -0,0 +1,54 @@ +//============================================================================ +// 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 + +namespace +{ +class DivideByVolumeWorklet : public vtkm::worklet::WorkletMapField +{ +public: + using ControlSignature = void(FieldInOut field); + using ExecutionSignature = void(_1); + + VTKM_EXEC_CONT + explicit DivideByVolumeWorklet(vtkm::Float64 volume) + : Volume(volume) + { + } + + template + VTKM_EXEC void operator()(T& value) const + { + value = static_cast(value / Volume); + } + +private: + vtkm::Float64 Volume; +}; // class DivideByVolumeWorklet +} + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ + +VTKM_CONT void ParticleDensityBase::DoDivideByVolume( + const vtkm::cont::UnknownArrayHandle& density) const +{ + auto volume = this->Spacing[0] * this->Spacing[1] * this->Spacing[2]; + this->Invoke(DivideByVolumeWorklet{ volume }, density); +} +} // namespace density_estimate +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/density_estimate/ParticleDensityBase.h b/vtkm/filter/density_estimate/ParticleDensityBase.h new file mode 100644 index 000000000..90c1ae512 --- /dev/null +++ b/vtkm/filter/density_estimate/ParticleDensityBase.h @@ -0,0 +1,75 @@ +//============================================================================ +// 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_filter_density_estimate_ParticleDensityBase_h +#define vtk_m_filter_density_estimate_ParticleDensityBase_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ +class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT ParticleDensityBase : public vtkm::filter::NewFilterField +{ +protected: + ParticleDensityBase(const vtkm::Id3& dimension, + const vtkm::Vec3f& origin, + const vtkm::Vec3f& spacing) + : Dimension(dimension) + , Origin(origin) + , Spacing(spacing) + , ComputeNumberDensity(false) + , DivideByVolume(true) + { + } + + ParticleDensityBase(const vtkm::Id3& dimension, const vtkm::Bounds& bounds) + : Dimension(dimension) + , Origin({ static_cast(bounds.X.Min), + static_cast(bounds.Y.Min), + static_cast(bounds.Z.Min) }) + , Spacing(vtkm::Vec3f{ static_cast(bounds.X.Length()), + static_cast(bounds.Y.Length()), + static_cast(bounds.Z.Length()) } / + Dimension) + , ComputeNumberDensity(false) + , DivideByVolume(true) + { + } + +public: + VTKM_CONT void SetComputeNumberDensity(bool yes) { this->ComputeNumberDensity = yes; } + + VTKM_CONT bool GetComputeNumberDensity() const { return this->ComputeNumberDensity; } + + VTKM_CONT void SetDivideByVolume(bool yes) { this->DivideByVolume = yes; } + + VTKM_CONT bool GetDivideByVolume() const { return this->DivideByVolume; } + +protected: + // Note: we are using the paradoxical "const ArrayHandle&" parameter whose content can actually + // be change by the function. + VTKM_CONT void DoDivideByVolume(const vtkm::cont::UnknownArrayHandle& array) const; + + vtkm::Id3 Dimension; // Cell dimension + vtkm::Vec3f Origin; + vtkm::Vec3f Spacing; + bool ComputeNumberDensity; + bool DivideByVolume; +}; +} // namespace density_estimate +} // namespace filter +} // namespace vtkm + +#endif //vtk_m_filter_density_estimate_ParticleDensityBase_h diff --git a/vtkm/filter/ParticleDensityCloudInCell.hxx b/vtkm/filter/density_estimate/ParticleDensityCloudInCell.cxx similarity index 58% rename from vtkm/filter/ParticleDensityCloudInCell.hxx rename to vtkm/filter/density_estimate/ParticleDensityCloudInCell.cxx index 1070a5347..4a0efd94b 100644 --- a/vtkm/filter/ParticleDensityCloudInCell.hxx +++ b/vtkm/filter/density_estimate/ParticleDensityCloudInCell.cxx @@ -8,13 +8,9 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_particle_density_cic_hxx -#define vtk_m_filter_particle_density_cic_hxx - -#include #include #include -#include +#include #include namespace vtkm @@ -74,25 +70,22 @@ namespace vtkm { namespace filter { -inline VTKM_CONT ParticleDensityCloudInCell::ParticleDensityCloudInCell(const vtkm::Id3& dimension, - const vtkm::Vec3f& origin, - const vtkm::Vec3f& spacing) +namespace density_estimate +{ +VTKM_CONT ParticleDensityCloudInCell::ParticleDensityCloudInCell(const vtkm::Id3& dimension, + const vtkm::Vec3f& origin, + const vtkm::Vec3f& spacing) : Superclass(dimension, origin, spacing) { } -inline VTKM_CONT ParticleDensityCloudInCell::ParticleDensityCloudInCell(const Id3& dimension, - const vtkm::Bounds& bounds) +VTKM_CONT ParticleDensityCloudInCell::ParticleDensityCloudInCell(const Id3& dimension, + const vtkm::Bounds& bounds) : Superclass(dimension, bounds) { } -template -inline VTKM_CONT vtkm::cont::DataSet ParticleDensityCloudInCell::DoExecute( - const cont::DataSet& dataSet, - const cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata&, - PolicyBase) +VTKM_CONT vtkm::cont::DataSet ParticleDensityCloudInCell::DoExecute(const cont::DataSet& input) { // Unlike ParticleDensityNGP, particle deposit mass on the grid points, thus it is natural to // return the density as PointField; @@ -104,30 +97,56 @@ inline VTKM_CONT vtkm::cont::DataSet ParticleDensityCloudInCell::DoExecute( locator.SetCoordinates(uniform.GetCoordinateSystem()); locator.Update(); - auto coords = dataSet.GetCoordinateSystem().GetDataAsMultiplexer(); + auto coords = input.GetCoordinateSystem().GetDataAsMultiplexer(); - vtkm::cont::ArrayHandle density; - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant(0, uniform.GetNumberOfPoints()), - density); + auto resolveType = [&, this](const auto& concrete) { + // use std::decay to remove const ref from the decltype of concrete. + using T = typename std::decay_t::ValueType; - this->Invoke(vtkm::worklet::CICWorklet{}, - coords, - field, - locator, - uniform.GetCellSet().template AsCellSet>(), - density); + // We create an ArrayHandle and pass it to the Worklet as AtomicArrayInOut. + // However, the ArrayHandle needs to be allocated and initialized first. + vtkm::cont::ArrayHandle density; + density.AllocateAndFill(uniform.GetNumberOfPoints(), 0); - if (DivideByVolume) - { - auto volume = this->Spacing[0] * this->Spacing[1] * this->Spacing[2]; - this->Invoke(DivideByVolumeWorklet{ volume }, density); - } + this->Invoke(vtkm::worklet::CICWorklet{}, + coords, + concrete, + locator, + uniform.GetCellSet().template AsCellSet>(), + density); - uniform.AddField(vtkm::cont::make_FieldPoint("density", density)); + if (DivideByVolume) + { + this->DoDivideByVolume(density); + } + uniform.AddField(vtkm::cont::make_FieldPoint("density", density)); + }; + + // Note: This is the so called Immediately-Invoked Function Expression (IIFE). Here we define + // a lambda expression and immediately call it at the end. This allows us to not declare an + // UnknownArrayHandle first and then assign it in the if-else statement. If I really want to + // show-off, I can even inline the `fieldArray` variable and turn it into a long expression. + auto fieldArray = [&, this]() -> vtkm::cont::UnknownArrayHandle { + if (this->ComputeNumberDensity) + { + return vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 }, + input.GetNumberOfPoints()); + } + else + { + return this->GetFieldFromDataSet(input).GetData(); + } + }(); + fieldArray.CastAndCallForTypes< + vtkm::TypeListFieldScalar, + vtkm::ListAppend>>( + resolveType); + + // Deposition of the input field to the output field is already mapping. No need to map other + // fields. return uniform; } - -} -} -#endif // vtk_m_filter_particle_density_cic_hxx +} // namespace density_estimate +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/density_estimate/ParticleDensityCloudInCell.h b/vtkm/filter/density_estimate/ParticleDensityCloudInCell.h new file mode 100644 index 000000000..9d3f99932 --- /dev/null +++ b/vtkm/filter/density_estimate/ParticleDensityCloudInCell.h @@ -0,0 +1,56 @@ +//============================================================================ +// 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_filter_density_estimate_ParticleDensityCIC_h +#define vtk_m_filter_density_estimate_ParticleDensityCIC_h + +#include + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ +/// \brief Estimate the density of particles using the Cloud-in-Cell method +/// This filter treats the CoordinateSystem of a DataSet as positions of particles. +/// The particles are infinitesimal in size with finite mass (or other scalar attributes +/// such as charge). The filter estimates density by imposing a regular grid as +/// specified in the constructor. It spreads the mass of each particle to its 8 nearest +/// neighboring grid points and summing the contribution of particles for each point +/// in the grid. +/// The mass of particles is established by setting the active field (using SetActiveField). +/// Note that the "mass" can actually be another quantity. For example, you could use +/// electrical charge in place of mass to compute the charge density. +/// Once the sum of the mass is computed for each grid point, the mass is divided by the +/// volume of the cell. Thus, the density will be computed as the units of the mass field +/// per the cubic units of the coordinate system. If you just want a sum of the mass in each +/// cell, turn off the DivideByVolume feature of this filter. +/// In addition, you can also simply count the number of particles in each cell by calling +/// SetComputeNumberDensity(true). +class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT ParticleDensityCloudInCell : public ParticleDensityBase +{ +public: + using Superclass = ParticleDensityBase; + + ParticleDensityCloudInCell(const vtkm::Id3& dimension, + const vtkm::Vec3f& origin, + const vtkm::Vec3f& spacing); + + ParticleDensityCloudInCell(const Id3& dimension, const vtkm::Bounds& bounds); + +private: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; +}; +} // namespace density_estimate +} // namespace filter +} // namespace vtkm + +#endif // vtk_m_filter_density_estimate_ParticleDensityCIC_h diff --git a/vtkm/filter/ParticleDensityNearestGridPoint.hxx b/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.cxx similarity index 56% rename from vtkm/filter/ParticleDensityNearestGridPoint.hxx rename to vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.cxx index c1c866fdb..17804f90a 100644 --- a/vtkm/filter/ParticleDensityNearestGridPoint.hxx +++ b/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.cxx @@ -8,14 +8,9 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_particle_density_ngp_hxx -#define vtk_m_filter_particle_density_ngp_hxx - -#include -#include #include #include -#include +#include #include namespace vtkm @@ -57,7 +52,9 @@ namespace vtkm { namespace filter { -inline VTKM_CONT ParticleDensityNearestGridPoint::ParticleDensityNearestGridPoint( +namespace density_estimate +{ +VTKM_CONT ParticleDensityNearestGridPoint::ParticleDensityNearestGridPoint( const vtkm::Id3& dimension, const vtkm::Vec3f& origin, const vtkm::Vec3f& spacing) @@ -65,20 +62,15 @@ inline VTKM_CONT ParticleDensityNearestGridPoint::ParticleDensityNearestGridPoin { } -inline VTKM_CONT ParticleDensityNearestGridPoint::ParticleDensityNearestGridPoint( +VTKM_CONT ParticleDensityNearestGridPoint::ParticleDensityNearestGridPoint( const Id3& dimension, const vtkm::Bounds& bounds) : Superclass(dimension, bounds) { } -template -inline VTKM_CONT vtkm::cont::DataSet ParticleDensityNearestGridPoint::DoExecute( - const vtkm::cont::DataSet& dataSet, - const vtkm::cont::ArrayHandle& - field, // particles' scala field to be deposited to the mesh, e.g. mass or charge - const vtkm::filter::FieldMetadata&, - vtkm::filter::PolicyBase) +VTKM_CONT vtkm::cont::DataSet ParticleDensityNearestGridPoint::DoExecute( + const vtkm::cont::DataSet& input) { // TODO: it really doesn't need to be a UniformGrid, any CellSet with CellLocator will work. // Make it another input rather an output generated. @@ -96,27 +88,51 @@ inline VTKM_CONT vtkm::cont::DataSet ParticleDensityNearestGridPoint::DoExecute( locator.SetCoordinates(uniform.GetCoordinateSystem()); locator.Update(); - auto coords = dataSet.GetCoordinateSystem().GetDataAsMultiplexer(); + auto coords = input.GetCoordinateSystem().GetDataAsMultiplexer(); - // We create an ArrayHandle and pass it to the Worklet as AtomicArrayInOut. - // However the ArrayHandle needs to be allocated and initialized first. The - // easiest way to do it is to copy from an ArrayHandleConstant - vtkm::cont::ArrayHandle density; - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant(0, uniform.GetNumberOfCells()), density); + auto resolveType = [&, this](const auto& concrete) { + // use std::decay to remove const ref from the decltype of concrete. + using T = typename std::decay_t::ValueType; - this->Invoke(vtkm::worklet::NGPWorklet{}, coords, field, locator, density); + // We create an ArrayHandle and pass it to the Worklet as AtomicArrayInOut. + // However, the ArrayHandle needs to be allocated and initialized first. + vtkm::cont::ArrayHandle density; + density.AllocateAndFill(uniform.GetNumberOfPoints(), 0); - if (DivideByVolume) - { - auto volume = this->Spacing[0] * this->Spacing[1] * this->Spacing[2]; - this->Invoke(DivideByVolumeWorklet{ volume }, density); - } + this->Invoke(vtkm::worklet::NGPWorklet{}, coords, concrete, locator, density); - uniform.AddField(vtkm::cont::make_FieldCell("density", density)); + if (DivideByVolume) + { + this->DoDivideByVolume(density); + } + uniform.AddField(vtkm::cont::make_FieldCell("density", density)); + }; + + // Note: This is the so called Immediately-Invoked Function Expression (IIFE). Here we define + // a lambda expression and immediately call it at the end. This allows us to not declare an + // UnknownArrayHandle first and then assign it in the if-else statement. If I really want to + // show-off, I can even inline the `fieldArray` variable and turn it into a long expression. + auto fieldArray = [&, this]() -> vtkm::cont::UnknownArrayHandle { + if (this->ComputeNumberDensity) + { + return vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 }, + input.GetNumberOfPoints()); + } + else + { + return this->GetFieldFromDataSet(input).GetData(); + } + }(); + fieldArray.CastAndCallForTypes< + vtkm::TypeListFieldScalar, + vtkm::ListAppend>>( + resolveType); + + // Deposition of the input field to the output field is already mapping. No need to map other + // fields. return uniform; } - } } -#endif //vtk_m_filter_particle_density_ngp_hxx +} diff --git a/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h b/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h new file mode 100644 index 000000000..f95947f2e --- /dev/null +++ b/vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h @@ -0,0 +1,55 @@ +//============================================================================ +// 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_filter_density_estimate_ParticleDensityNGP_h +#define vtk_m_filter_density_estimate_ParticleDensityNGP_h + +#include + +namespace vtkm +{ +namespace filter +{ +namespace density_estimate +{ +/// \brief Estimate the density of particles using the Nearest Grid Point method +/// This filter treats the CoordinateSystem of a DataSet as positions of particles. +/// The particles are infinitesimal in size with finite mass (or other scalar attributes +/// such as charge). The filter estimates density by imposing a regular grid as +/// specified in the constructor and summing the mass of particles within each cell +/// in the grid. +/// The mass of particles is established by setting the active field (using SetActiveField). +/// Note that the "mass" can actually be another quantity. For example, you could use +/// electrical charge in place of mass to compute the charge density. +/// Once the sum of the mass is computed for each grid cell, the mass is divided by the +/// volume of the cell. Thus, the density will be computed as the units of the mass field +/// per the cubic units of the coordinate system. If you just want a sum of the mass in each +/// cell, turn off the DivideByVolume feature of this filter. +/// In addition, you can also simply count the number of particles in each cell by calling +/// SetComputeNumberDensity(true). +class VTKM_FILTER_DENSITY_ESTIMATE_EXPORT ParticleDensityNearestGridPoint + : public ParticleDensityBase +{ +public: + using Superclass = ParticleDensityBase; + + ParticleDensityNearestGridPoint(const vtkm::Id3& dimension, + const vtkm::Vec3f& origin, + const vtkm::Vec3f& spacing); + + ParticleDensityNearestGridPoint(const vtkm::Id3& dimension, const vtkm::Bounds& bounds); + +private: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; +}; +} // namespace density_estimate +} // namespace filter +} // namespace vtkm +#endif //vtk_m_filter_density_estimate_ParticleDensityNGP_h diff --git a/vtkm/filter/density_estimate/testing/CMakeLists.txt b/vtkm/filter/density_estimate/testing/CMakeLists.txt new file mode 100644 index 000000000..540c67707 --- /dev/null +++ b/vtkm/filter/density_estimate/testing/CMakeLists.txt @@ -0,0 +1,28 @@ +##============================================================================ +## 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. +##============================================================================ + +set(unit_tests + UnitTestEntropyFilter.cxx + UnitTestHistogramFilter.cxx + UnitTestNDEntropyFilter.cxx + UnitTestNDHistogramFilter.cxx + UnitTestPartitionedDataSetHistogramFilter.cxx + UnitTestParticleDensity.cxx) + +set(libraries + vtkm_filter_density_estimate + vtkm_source) + +vtkm_unit_tests( + SOURCES ${unit_tests} + LIBRARIES ${libraries} + ALL_BACKENDS # UnitTestParticleDensity.cxx uses DescriptiveStatistcs worklet + USE_VTKM_JOB_POOL +) diff --git a/vtkm/filter/testing/UnitTestEntropyFilter.cxx b/vtkm/filter/density_estimate/testing/UnitTestEntropyFilter.cxx similarity index 95% rename from vtkm/filter/testing/UnitTestEntropyFilter.cxx rename to vtkm/filter/density_estimate/testing/UnitTestEntropyFilter.cxx index f77bc520e..7e3f06f15 100644 --- a/vtkm/filter/testing/UnitTestEntropyFilter.cxx +++ b/vtkm/filter/density_estimate/testing/UnitTestEntropyFilter.cxx @@ -8,7 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include @@ -24,7 +24,7 @@ void TestEntropy() vtkm::source::Tangle tangle(dims); vtkm::cont::DataSet dataSet = tangle.Execute(); - vtkm::filter::Entropy entropyFilter; + vtkm::filter::density_estimate::Entropy entropyFilter; ///// calculate entropy of "tangle" field of the data set ///// entropyFilter.SetNumberOfBins(50); //set number of bins diff --git a/vtkm/filter/testing/UnitTestHistogramFilter.cxx b/vtkm/filter/density_estimate/testing/UnitTestHistogramFilter.cxx similarity index 99% rename from vtkm/filter/testing/UnitTestHistogramFilter.cxx rename to vtkm/filter/density_estimate/testing/UnitTestHistogramFilter.cxx index 5074a9554..5b6c8b6eb 100644 --- a/vtkm/filter/testing/UnitTestHistogramFilter.cxx +++ b/vtkm/filter/density_estimate/testing/UnitTestHistogramFilter.cxx @@ -8,7 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include @@ -295,7 +295,7 @@ void TestHistogram() // Data attached is the poisson distribution vtkm::cont::DataSet ds = MakeTestDataSet(); - vtkm::filter::Histogram histogram; + vtkm::filter::density_estimate::Histogram histogram; // Run data histogram.SetNumberOfBins(10); diff --git a/vtkm/filter/testing/UnitTestNDEntropyFilter.cxx b/vtkm/filter/density_estimate/testing/UnitTestNDEntropyFilter.cxx similarity index 99% rename from vtkm/filter/testing/UnitTestNDEntropyFilter.cxx rename to vtkm/filter/density_estimate/testing/UnitTestNDEntropyFilter.cxx index 0fe67abe0..1fe9c0a25 100644 --- a/vtkm/filter/testing/UnitTestNDEntropyFilter.cxx +++ b/vtkm/filter/density_estimate/testing/UnitTestNDEntropyFilter.cxx @@ -8,7 +8,7 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include +#include #include #include @@ -177,7 +177,7 @@ void RunTest() { vtkm::cont::DataSet ds = MakeTestDataSet(); - vtkm::filter::NDEntropy ndEntropyFilter; + vtkm::filter::density_estimate::NDEntropy ndEntropyFilter; ndEntropyFilter.AddFieldAndBin("fieldA", 10); ndEntropyFilter.AddFieldAndBin("fieldB", 10); diff --git a/vtkm/filter/testing/UnitTestNDHistogramFilter.cxx b/vtkm/filter/density_estimate/testing/UnitTestNDHistogramFilter.cxx similarity index 97% rename from vtkm/filter/testing/UnitTestNDHistogramFilter.cxx rename to vtkm/filter/density_estimate/testing/UnitTestNDHistogramFilter.cxx index e368377a3..09e61fcd6 100644 --- a/vtkm/filter/testing/UnitTestNDHistogramFilter.cxx +++ b/vtkm/filter/density_estimate/testing/UnitTestNDHistogramFilter.cxx @@ -8,10 +8,8 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#include - -#include #include +#include namespace { @@ -60,7 +58,7 @@ void RunTest() { vtkm::cont::DataSet ds = MakeTestDataSet(); - vtkm::filter::NDHistogram ndHistFilter; + vtkm::filter::density_estimate::NDHistogram ndHistFilter; ndHistFilter.AddFieldAndBin("fieldA", 4); ndHistFilter.AddFieldAndBin("fieldB", 4); diff --git a/vtkm/filter/testing/UnitTestParticleDensity.cxx b/vtkm/filter/density_estimate/testing/UnitTestParticleDensity.cxx similarity index 86% rename from vtkm/filter/testing/UnitTestParticleDensity.cxx rename to vtkm/filter/density_estimate/testing/UnitTestParticleDensity.cxx index 1cf7bb039..6a8b6efc2 100644 --- a/vtkm/filter/testing/UnitTestParticleDensity.cxx +++ b/vtkm/filter/density_estimate/testing/UnitTestParticleDensity.cxx @@ -8,11 +8,13 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ +#include +#include #include #include #include -#include -#include +#include +#include #include void TestNGP() @@ -27,7 +29,7 @@ void TestNGP() vtkm::cont::ArrayHandleRandomUniformReal(N, 0xdeed), vtkm::cont::ArrayHandleRandomUniformReal(N, 0xabba)); vtkm::cont::ArrayHandle positions; - vtkm::cont::ArrayCopy(composite, positions); + vtkm::cont::ArrayCopyDevice(composite, positions); vtkm::cont::ArrayHandle connectivity; vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleIndex(N), connectivity); @@ -36,12 +38,12 @@ void TestNGP() positions, vtkm::CellShapeTagVertex{}, 1, connectivity); vtkm::cont::ArrayHandle mass; - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleRandomUniformReal(N, 0xd1ce), - mass); + vtkm::cont::ArrayCopyDevice( + vtkm::cont::ArrayHandleRandomUniformReal(N, 0xd1ce), mass); dataSet.AddCellField("mass", mass); auto cellDims = vtkm::Id3{ 3, 3, 3 }; - vtkm::filter::ParticleDensityNearestGridPoint filter{ + vtkm::filter::density_estimate::ParticleDensityNearestGridPoint filter{ cellDims, { 0.f, 0.f, 0.f }, vtkm::Vec3f{ 1.f / 3.f, 1.f / 3.f, 1.f / 3.f } }; filter.SetActiveField("mass"); @@ -78,7 +80,7 @@ void TestCIC() vtkm::cont::ArrayHandleRandomUniformReal(N, 0xdeed), vtkm::cont::ArrayHandleRandomUniformReal(N, 0xabba)); vtkm::cont::ArrayHandle positions; - vtkm::cont::ArrayCopy(composite, positions); + vtkm::cont::ArrayCopyDevice(composite, positions); vtkm::cont::ArrayHandle connectivity; vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleIndex(N), connectivity); @@ -87,13 +89,14 @@ void TestCIC() positions, vtkm::CellShapeTagVertex{}, 1, connectivity); vtkm::cont::ArrayHandle mass; - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleRandomUniformReal(N, 0xd1ce), mass); + vtkm::cont::ArrayCopyDevice(vtkm::cont::ArrayHandleRandomUniformReal(N, 0xd1ce), + mass); dataSet.AddCellField("mass", mass); auto cellDims = vtkm::Id3{ 3, 3, 3 }; - vtkm::filter::ParticleDensityCloudInCell filter{ cellDims, - { 0.f, 0.f, 0.f }, - vtkm::Vec3f{ 1.f / 3.f, 1.f / 3.f, 1.f / 3.f } }; + vtkm::filter::density_estimate::ParticleDensityCloudInCell filter{ + cellDims, { 0.f, 0.f, 0.f }, vtkm::Vec3f{ 1.f / 3.f, 1.f / 3.f, 1.f / 3.f } + }; filter.SetActiveField("mass"); auto density = filter.Execute(dataSet); diff --git a/vtkm/filter/testing/UnitTestPartitionedDataSetHistogramFilter.cxx b/vtkm/filter/density_estimate/testing/UnitTestPartitionedDataSetHistogramFilter.cxx similarity index 97% rename from vtkm/filter/testing/UnitTestPartitionedDataSetHistogramFilter.cxx rename to vtkm/filter/density_estimate/testing/UnitTestPartitionedDataSetHistogramFilter.cxx index 4423e3281..20a58c810 100644 --- a/vtkm/filter/testing/UnitTestPartitionedDataSetHistogramFilter.cxx +++ b/vtkm/filter/density_estimate/testing/UnitTestPartitionedDataSetHistogramFilter.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 @@ -102,7 +102,7 @@ static void TestPartitionedDataSetHistogram() AddField(partition2, 100.0, 500.0, 1024, "double"); mb.AppendPartition(partition2); - vtkm::filter::Histogram histogram; + vtkm::filter::density_estimate::Histogram histogram; histogram.SetActiveField("double"); auto result = histogram.Execute(mb); VTKM_TEST_ASSERT(result.GetNumberOfPartitions() == 1, "Expecting 1 partition."); diff --git a/vtkm/filter/density_estimate/worklet/CMakeLists.txt b/vtkm/filter/density_estimate/worklet/CMakeLists.txt new file mode 100644 index 000000000..d3b3bd1c7 --- /dev/null +++ b/vtkm/filter/density_estimate/worklet/CMakeLists.txt @@ -0,0 +1,17 @@ +##============================================================================ +## 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. +##============================================================================ + +set(headers + FieldEntropy.h + FieldHistogram.h + NDimsEntropy.h + NDimsHistogram.h) + +vtkm_declare_headers(${headers}) diff --git a/vtkm/worklet/FieldEntropy.h b/vtkm/filter/density_estimate/worklet/FieldEntropy.h similarity index 97% rename from vtkm/worklet/FieldEntropy.h rename to vtkm/filter/density_estimate/worklet/FieldEntropy.h index 2b8523e48..d9688fbdb 100644 --- a/vtkm/worklet/FieldEntropy.h +++ b/vtkm/filter/density_estimate/worklet/FieldEntropy.h @@ -15,8 +15,8 @@ #include #include #include +#include #include -#include #include #include diff --git a/vtkm/worklet/FieldHistogram.h b/vtkm/filter/density_estimate/worklet/FieldHistogram.h similarity index 100% rename from vtkm/worklet/FieldHistogram.h rename to vtkm/filter/density_estimate/worklet/FieldHistogram.h diff --git a/vtkm/worklet/NDimsEntropy.h b/vtkm/filter/density_estimate/worklet/NDimsEntropy.h similarity index 97% rename from vtkm/worklet/NDimsEntropy.h rename to vtkm/filter/density_estimate/worklet/NDimsEntropy.h index e64aef44a..b3d75b3e9 100644 --- a/vtkm/worklet/NDimsEntropy.h +++ b/vtkm/filter/density_estimate/worklet/NDimsEntropy.h @@ -15,8 +15,8 @@ #include #include #include +#include #include -#include #include #include diff --git a/vtkm/worklet/NDimsHistogram.h b/vtkm/filter/density_estimate/worklet/NDimsHistogram.h similarity index 100% rename from vtkm/worklet/NDimsHistogram.h rename to vtkm/filter/density_estimate/worklet/NDimsHistogram.h diff --git a/vtkm/filter/entity_extraction/CMakeLists.txt b/vtkm/filter/entity_extraction/CMakeLists.txt index 0b6a587ba..cd350b19f 100644 --- a/vtkm/filter/entity_extraction/CMakeLists.txt +++ b/vtkm/filter/entity_extraction/CMakeLists.txt @@ -9,14 +9,24 @@ ##============================================================================ set(entity_extraction_headers ExternalFaces.h + ExtractGeometry.h ExtractPoints.h + ExtractStructured.h + GhostCellRemove.h + Mask.h MaskPoints.h + Threshold.h ThresholdPoints.h ) set(entity_extraction_sources_device ExternalFaces.cxx + ExtractGeometry.cxx ExtractPoints.cxx + ExtractStructured.cxx + GhostCellRemove.cxx + Mask.cxx MaskPoints.cxx + Threshold.cxx ThresholdPoints.cxx ) diff --git a/vtkm/filter/entity_extraction/ExternalFaces.cxx b/vtkm/filter/entity_extraction/ExternalFaces.cxx index 40beff9fc..1fb314fdc 100644 --- a/vtkm/filter/entity_extraction/ExternalFaces.cxx +++ b/vtkm/filter/entity_extraction/ExternalFaces.cxx @@ -46,7 +46,8 @@ vtkm::cont::DataSet ExternalFaces::GenerateOutput(const vtkm::cont::DataSet& inp bool hasCellFields = false; for (vtkm::Id fieldIdx = 0; fieldIdx < numFields && !hasCellFields; ++fieldIdx) { - hasCellFields = input.GetField(fieldIdx).IsFieldCell(); + const auto& f = input.GetField(fieldIdx); + hasCellFields = f.IsFieldCell(); } if (!hasCellFields) diff --git a/vtkm/filter/entity_extraction/ExternalFaces.h b/vtkm/filter/entity_extraction/ExternalFaces.h index 677429c48..f15dd276c 100644 --- a/vtkm/filter/entity_extraction/ExternalFaces.h +++ b/vtkm/filter/entity_extraction/ExternalFaces.h @@ -36,7 +36,7 @@ class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExternalFaces : public vtkm::filter:: { public: ExternalFaces(); - ~ExternalFaces(); + ~ExternalFaces() override; // New Design: I am too lazy to make this filter thread-safe. Let's use it as an example of // thread un-safe filter. diff --git a/vtkm/filter/ExtractGeometry.hxx b/vtkm/filter/entity_extraction/ExtractGeometry.cxx similarity index 70% rename from vtkm/filter/ExtractGeometry.hxx rename to vtkm/filter/entity_extraction/ExtractGeometry.cxx index 2cf06822c..187836a1e 100644 --- a/vtkm/filter/ExtractGeometry.hxx +++ b/vtkm/filter/entity_extraction/ExtractGeometry.cxx @@ -7,18 +7,15 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ - -#ifndef vtk_m_filter_ExtractGeometry_hxx -#define vtk_m_filter_ExtractGeometry_hxx - -#include -#include #include #include +#include +#include +#include + namespace { - struct CallWorker { vtkm::cont::UnknownCellSet& Output; @@ -58,40 +55,68 @@ struct CallWorker } }; -} // end anon namespace +bool DoMapField(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + const vtkm::worklet::ExtractGeometry& worklet) +{ + if (field.IsFieldPoint()) + { + result.AddField(field); + return true; + } + else if (field.IsFieldCell()) + { + vtkm::cont::ArrayHandle permutation = worklet.GetValidCellIds(); + return vtkm::filter::MapFieldPermutation(field, permutation, result); + } + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } +} +} // anonymous namespace namespace vtkm { namespace filter { - +namespace entity_extraction +{ //----------------------------------------------------------------------------- -template -vtkm::cont::DataSet ExtractGeometry::DoExecute(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy) +vtkm::cont::DataSet ExtractGeometry::DoExecute(const vtkm::cont::DataSet& input) { // extract the input cell set and coordinates const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); const vtkm::cont::CoordinateSystem& coords = input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()); + vtkm::worklet::ExtractGeometry worklet; vtkm::cont::UnknownCellSet outCells; CallWorker worker(outCells, - this->Worklet, + worklet, coords, this->Function, this->ExtractInside, this->ExtractBoundaryCells, this->ExtractOnlyBoundaryCells); - vtkm::filter::ApplyPolicyCellSet(cells, policy, *this).CastAndCall(worker); + cells.CastAndCallForTypes(worker); // create the output dataset vtkm::cont::DataSet output; output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); output.SetCellSet(outCells); + + auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); }; + this->MapFieldsOntoOutput(input, output, mapper); + return output; } -} -} -#endif +} // namespace entity_extraction +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/entity_extraction/ExtractGeometry.h b/vtkm/filter/entity_extraction/ExtractGeometry.h new file mode 100644 index 000000000..b4f0c37c6 --- /dev/null +++ b/vtkm/filter/entity_extraction/ExtractGeometry.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_fulter_entity_extraction_ExtractGeometry_h +#define vtk_m_fulter_entity_extraction_ExtractGeometry_h + +#include +#include +#include + +namespace vtkm +{ +namespace worklet +{ +// Forward declaration for the worklet so we don't need to include the worklet header file +// which would require user code to be compilerd by device compiler. +class ExtractGeometry; +} +namespace filter +{ +namespace entity_extraction +{ +/// \brief Extract a subset of geometry based on an implicit function +/// +/// Extracts from its input geometry all cells that are either +/// completely inside or outside of a specified implicit function. Any type of +/// data can be input to this filter. +/// +/// To use this filter you must specify an implicit function. You must also +/// specify whether to extract cells laying inside or outside of the implicit +/// function. (The inside of an implicit function is the negative values +/// region.) An option exists to extract cells that are neither inside or +/// outside (i.e., boundary). +/// +/// This differs from Clip in that Clip will subdivide boundary cells into new +/// cells, while this filter will not, producing a more 'crinkly' output. +/// +class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExtractGeometry : public vtkm::filter::NewFilterField +{ +public: + // Set the volume of interest to extract + void SetImplicitFunction(const vtkm::ImplicitFunctionGeneral& func) { this->Function = func; } + + const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; } + + VTKM_CONT + bool GetExtractInside() const { return this->ExtractInside; } + VTKM_CONT + void SetExtractInside(bool value) { this->ExtractInside = value; } + VTKM_CONT + void ExtractInsideOn() { this->ExtractInside = true; } + VTKM_CONT + void ExtractInsideOff() { this->ExtractInside = false; } + + VTKM_CONT + bool GetExtractBoundaryCells() const { return this->ExtractBoundaryCells; } + VTKM_CONT + void SetExtractBoundaryCells(bool value) { this->ExtractBoundaryCells = value; } + VTKM_CONT + void ExtractBoundaryCellsOn() { this->ExtractBoundaryCells = true; } + VTKM_CONT + void ExtractBoundaryCellsOff() { this->ExtractBoundaryCells = false; } + + VTKM_CONT + bool GetExtractOnlyBoundaryCells() const { return this->ExtractOnlyBoundaryCells; } + VTKM_CONT + void SetExtractOnlyBoundaryCells(bool value) { this->ExtractOnlyBoundaryCells = value; } + VTKM_CONT + void ExtractOnlyBoundaryCellsOn() { this->ExtractOnlyBoundaryCells = true; } + VTKM_CONT + void ExtractOnlyBoundaryCellsOff() { this->ExtractOnlyBoundaryCells = false; } + +private: + VTKM_CONT + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + bool ExtractInside = true; + bool ExtractBoundaryCells = false; + bool ExtractOnlyBoundaryCells = false; + vtkm::ImplicitFunctionGeneral Function; +}; +} +} +} // namespace vtkm::filter + +#endif // vtk_m_fulter_entity_extraction_ExtractGeometry_h diff --git a/vtkm/filter/entity_extraction/ExtractPoints.cxx b/vtkm/filter/entity_extraction/ExtractPoints.cxx index fff661373..fd53ede8e 100644 --- a/vtkm/filter/entity_extraction/ExtractPoints.cxx +++ b/vtkm/filter/entity_extraction/ExtractPoints.cxx @@ -13,6 +13,29 @@ #include #include +namespace +{ +bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::Field& field) +{ + // point data is copied as is because it was not collapsed + if (field.IsFieldPoint()) + { + result.AddField(field); + return true; + } + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + // cell data does not apply + return false; + } +} +} // anonymous namespace + namespace vtkm { namespace filter @@ -40,7 +63,7 @@ vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& input) output.SetCellSet(outCellSet); output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); - auto mapper = [&, this](auto& result, const auto& f) { this->MapFieldOntoOutput(result, f); }; + auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f); }; this->MapFieldsOntoOutput(input, output, mapper); // compact the unused points in the output dataset @@ -57,27 +80,6 @@ vtkm::cont::DataSet ExtractPoints::DoExecute(const vtkm::cont::DataSet& input) } } -//----------------------------------------------------------------------------- -VTKM_CONT bool ExtractPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) -{ - // point data is copied as is because it was not collapsed - if (field.IsFieldPoint()) - { - result.AddField(field); - return true; - } - else if (field.IsFieldGlobal()) - { - result.AddField(field); - return true; - } - else - { - // cell data does not apply - return false; - } -} } // namespace entity_extraction } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/entity_extraction/ExtractPoints.h b/vtkm/filter/entity_extraction/ExtractPoints.h index e8def5d69..98942c1d0 100644 --- a/vtkm/filter/entity_extraction/ExtractPoints.h +++ b/vtkm/filter/entity_extraction/ExtractPoints.h @@ -51,7 +51,7 @@ public: const vtkm::ImplicitFunctionGeneral& GetImplicitFunction() const { return this->Function; } VTKM_CONT - bool GetExtractInside() { return this->ExtractInside; } + bool GetExtractInside() const { return this->ExtractInside; } VTKM_CONT void SetExtractInside(bool value) { this->ExtractInside = value; } VTKM_CONT @@ -63,9 +63,6 @@ private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; - //Map a new field onto the resulting dataset after running the filter - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field); - bool ExtractInside = true; vtkm::ImplicitFunctionGeneral Function; diff --git a/vtkm/filter/entity_extraction/ExtractStructured.cxx b/vtkm/filter/entity_extraction/ExtractStructured.cxx new file mode 100644 index 000000000..257da786a --- /dev/null +++ b/vtkm/filter/entity_extraction/ExtractStructured.cxx @@ -0,0 +1,86 @@ +//============================================================================ +// 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_CONT bool DoMapField(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + const vtkm::cont::ArrayHandle& CellFieldMap, + const vtkm::cont::ArrayHandle& PointFieldMap) +{ + if (field.IsFieldPoint()) + { + return vtkm::filter::MapFieldPermutation(field, PointFieldMap, result); + } + else if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation(field, CellFieldMap, result); + } + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } +} +} // anonymous namespace + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ +//----------------------------------------------------------------------------- +vtkm::cont::DataSet ExtractStructured::DoExecute(const vtkm::cont::DataSet& input) +{ + const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); + const vtkm::cont::CoordinateSystem& coordinates = input.GetCoordinateSystem(); + + vtkm::worklet::ExtractStructured worklet; + auto cellset = worklet.Run(cells.ResetCellSetList(), + this->VOI, + this->SampleRate, + this->IncludeBoundary, + this->IncludeOffset); + + auto coords = worklet.MapCoordinates(coordinates); + vtkm::cont::CoordinateSystem outputCoordinates(coordinates.GetName(), coords); + + vtkm::cont::DataSet output; + output.SetCellSet(vtkm::cont::UnknownCellSet(cellset)); + output.AddCoordinateSystem(outputCoordinates); + + // Create map arrays for mapping fields. Could potentially save some time to first check to see + // if these arrays would be used. + auto CellFieldMap = + worklet.ProcessCellField(vtkm::cont::ArrayHandleIndex(input.GetNumberOfCells())); + auto PointFieldMap = + worklet.ProcessPointField(vtkm::cont::ArrayHandleIndex(input.GetNumberOfPoints())); + + auto mapper = [&](auto& result, const auto& f) { + DoMapField(result, f, CellFieldMap, PointFieldMap); + }; + this->MapFieldsOntoOutput(input, output, mapper); + + return output; +} + +} // namespace entity_extraction +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/entity_extraction/ExtractStructured.h b/vtkm/filter/entity_extraction/ExtractStructured.h new file mode 100644 index 000000000..5218a0a00 --- /dev/null +++ b/vtkm/filter/entity_extraction/ExtractStructured.h @@ -0,0 +1,98 @@ +//============================================================================ +// 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_filter_entity_extraction_ExtractStructured_h +#define vtk_m_filter_entity_extraction_ExtractStructured_h + +#include +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ +/// \brief Select piece (e.g., volume of interest) and/or subsample structured points dataset +/// +/// Select or subsample a portion of an input structured dataset. The selected +/// portion of interested is referred to as the Volume Of Interest, or VOI. +/// The output of this filter is a structured dataset. The filter treats input +/// data of any topological dimension (i.e., point, line, plane, or volume) and +/// can generate output data of any topological dimension. +/// +/// To use this filter set the VOI ivar which are i-j-k min/max indices that +/// specify a rectangular region in the data. (Note that these are 0-offset.) +/// You can also specify a sampling rate to subsample the data. +/// +/// Typical applications of this filter are to extract a slice from a volume +/// for image processing, subsampling large volumes to reduce data size, or +/// extracting regions of a volume with interesting data. +/// +class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT ExtractStructured : public vtkm::filter::NewFilterField +{ +public: + // Set the bounding box for the volume of interest + VTKM_CONT + vtkm::RangeId3 GetVOI() const { return this->VOI; } + + VTKM_CONT + void SetVOI(vtkm::Id i0, vtkm::Id i1, vtkm::Id j0, vtkm::Id j1, vtkm::Id k0, vtkm::Id k1) + { + this->VOI = vtkm::RangeId3(i0, i1, j0, j1, k0, k1); + } + VTKM_CONT + void SetVOI(vtkm::Id extents[6]) { this->VOI = vtkm::RangeId3(extents); } + VTKM_CONT + void SetVOI(vtkm::Id3 minPoint, vtkm::Id3 maxPoint) + { + this->VOI = vtkm::RangeId3(minPoint, maxPoint); + } + VTKM_CONT + void SetVOI(const vtkm::RangeId3& voi) { this->VOI = voi; } + + /// Get the Sampling rate + VTKM_CONT + vtkm::Id3 GetSampleRate() const { return this->SampleRate; } + + /// Set the Sampling rate + VTKM_CONT + void SetSampleRate(vtkm::Id i, vtkm::Id j, vtkm::Id k) { this->SampleRate = vtkm::Id3(i, j, k); } + + /// Set the Sampling rate + VTKM_CONT + void SetSampleRate(vtkm::Id3 sampleRate) { this->SampleRate = sampleRate; } + + /// Get if we should include the outer boundary on a subsample + VTKM_CONT + bool GetIncludeBoundary() const { return this->IncludeBoundary; } + /// Set if we should include the outer boundary on a subsample + VTKM_CONT + void SetIncludeBoundary(bool value) { this->IncludeBoundary = value; } + + VTKM_CONT + void SetIncludeOffset(bool value) { this->IncludeOffset = value; } + +private: + VTKM_CONT + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + vtkm::RangeId3 VOI = vtkm::RangeId3(0, -1, 0, -1, 0, -1); + vtkm::Id3 SampleRate = { 1, 1, 1 }; + bool IncludeBoundary = false; + bool IncludeOffset = false; +}; + +} // namespace entity_extraction +} // namespace filter +} // namespace vtkm + +#endif // vtk_m_filter_entity_extraction_ExtractStructured_h diff --git a/vtkm/filter/GhostCellRemove.hxx b/vtkm/filter/entity_extraction/GhostCellRemove.cxx similarity index 82% rename from vtkm/filter/GhostCellRemove.hxx rename to vtkm/filter/entity_extraction/GhostCellRemove.cxx index c01c46dce..31b48b02b 100644 --- a/vtkm/filter/GhostCellRemove.hxx +++ b/vtkm/filter/entity_extraction/GhostCellRemove.cxx @@ -8,28 +8,22 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_GhostCellRemove_hxx -#define vtk_m_filter_GhostCellRemove_hxx -#include - -#include -#include -#include +#include #include -#include -#include +#include #include -#include +#include +#include +#include namespace { - class RemoveAllGhosts { public: VTKM_CONT - RemoveAllGhosts() {} + RemoveAllGhosts() = default; VTKM_EXEC bool operator()(const vtkm::UInt8& value) const { return (value == 0); } }; @@ -44,7 +38,7 @@ public: } VTKM_CONT - RemoveGhostByType(const vtkm::UInt8& val) + explicit RemoveGhostByType(const vtkm::UInt8& val) : RemoveType(static_cast(~val)) { } @@ -279,35 +273,53 @@ bool CanDoStructuredStrip(const vtkm::cont::UnknownCellSet& cells, return canDo; } +bool DoMapField(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + const vtkm::worklet::Threshold& worklet) +{ + if (field.IsFieldPoint()) + { + //we copy the input handle to the result dataset, reusing the metadata + result.AddField(field); + return true; + } + else if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation(field, worklet.GetValidCellIds(), result); + } + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + return false; + } +} } // end anon namespace namespace vtkm { namespace filter { - +namespace entity_extraction +{ //----------------------------------------------------------------------------- -inline VTKM_CONT GhostCellRemove::GhostCellRemove() - : vtkm::filter::FilterDataSetWithField() - , RemoveAll(false) - , RemoveField(false) - , RemoveVals(0) +VTKM_CONT GhostCellRemove::GhostCellRemove() { this->SetActiveField("vtkmGhostCells"); this->SetFieldsToPass("vtkmGhostCells", vtkm::filter::FieldSelection::MODE_EXCLUDE); } //----------------------------------------------------------------------------- -template -inline VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute( - const vtkm::cont::DataSet& input, - const vtkm::cont::ArrayHandle& field, - const vtkm::filter::FieldMetadata& fieldMeta, - vtkm::filter::PolicyBase policy) +VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute(const vtkm::cont::DataSet& input) { - //get the cells and coordinates of the dataset const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); - vtkm::cont::UnknownCellSet cellOut; + const auto& field = this->GetFieldFromDataSet(input); + + vtkm::cont::ArrayHandle fieldArray; + vtkm::cont::ArrayCopyShallowIfPossible(field.GetData(), fieldArray); //Preserve structured output where possible. if (cells.CanConvert>() || @@ -316,9 +328,9 @@ inline VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute( { vtkm::RangeId3 range; if (CanDoStructuredStrip( - cells, field, this->Invoke, this->GetRemoveAllGhost(), this->GetRemoveType(), range)) + cells, fieldArray, this->Invoke, this->GetRemoveAllGhost(), this->GetRemoveType(), range)) { - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; extract.SetInvoker(this->Invoke); vtkm::RangeId3 erange( range.X.Min, range.X.Max + 2, range.Y.Min, range.Y.Max + 2, range.Z.Min, range.Z.Max + 2); @@ -334,19 +346,22 @@ inline VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute( } } + vtkm::cont::UnknownCellSet cellOut; + vtkm::worklet::Threshold worklet; + if (this->GetRemoveAllGhost()) { - cellOut = this->Worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this), - field, - fieldMeta.GetAssociation(), - RemoveAllGhosts()); + cellOut = worklet.Run(cells.ResetCellSetList(), + fieldArray, + field.GetAssociation(), + RemoveAllGhosts()); } else if (this->GetRemoveByType()) { - cellOut = this->Worklet.Run(vtkm::filter::ApplyPolicyCellSet(cells, policy, *this), - field, - fieldMeta.GetAssociation(), - RemoveGhostByType(this->GetRemoveType())); + cellOut = worklet.Run(cells.ResetCellSetList(), + fieldArray, + field.GetAssociation(), + RemoveGhostByType(this->GetRemoveType())); } else { @@ -357,36 +372,12 @@ inline VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute( output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); output.SetCellSet(cellOut); + auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); }; + this->MapFieldsOntoOutput(input, output, mapper); + return output; } -//----------------------------------------------------------------------------- -template -VTKM_CONT bool GhostCellRemove::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase) -{ - if (field.IsFieldPoint()) - { - //we copy the input handle to the result dataset, reusing the metadata - result.AddField(field); - return true; - } - else if (field.IsFieldCell()) - { - return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result); - } - else if (field.IsFieldGlobal()) - { - result.AddField(field); - return true; - } - else - { - return false; - } } } } - -#endif //vtk_m_filter_GhostCellRemove_hxx diff --git a/vtkm/filter/entity_extraction/GhostCellRemove.h b/vtkm/filter/entity_extraction/GhostCellRemove.h new file mode 100644 index 000000000..41c17328f --- /dev/null +++ b/vtkm/filter/entity_extraction/GhostCellRemove.h @@ -0,0 +1,65 @@ +//============================================================================ +// 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_filter_entity_extraction_GhostCellRemove_h +#define vtk_m_filter_entity_extraction_GhostCellRemove_h + +#include +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ +/// \brief Removes ghost cells +/// +class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT GhostCellRemove : public vtkm::filter::NewFilterField +{ +public: + VTKM_CONT + GhostCellRemove(); + + VTKM_CONT + void RemoveGhostField() { this->RemoveField = true; } + VTKM_CONT + void RemoveAllGhost() { this->RemoveAll = true; } + VTKM_CONT + void RemoveByType(const vtkm::UInt8& vals) + { + this->RemoveAll = false; + this->RemoveVals = vals; + } + VTKM_CONT + bool GetRemoveGhostField() const { return this->RemoveField; } + VTKM_CONT + bool GetRemoveAllGhost() const { return this->RemoveAll; } + + VTKM_CONT + bool GetRemoveByType() const { return !this->RemoveAll; } + VTKM_CONT + vtkm::UInt8 GetRemoveType() const { return this->RemoveVals; } + +private: + VTKM_CONT + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + bool RemoveAll = false; + bool RemoveField = false; + vtkm::UInt8 RemoveVals = 0; +}; + +} // namespace entity_extraction +} // namespace filter +} // namespace vtkm + +#endif // vtk_m_filter_entity_extraction_GhostCellRemove_h diff --git a/vtkm/filter/Mask.hxx b/vtkm/filter/entity_extraction/Mask.cxx similarity index 59% rename from vtkm/filter/Mask.hxx rename to vtkm/filter/entity_extraction/Mask.cxx index 569f8fc3c..bbd74b27e 100644 --- a/vtkm/filter/Mask.hxx +++ b/vtkm/filter/entity_extraction/Mask.cxx @@ -7,14 +7,12 @@ // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ -#ifndef vtk_m_filter_Mask_hxx -#define vtk_m_filter_Mask_hxx - #include +#include +#include namespace { - struct CallWorklet { vtkm::Id Stride; @@ -35,43 +33,9 @@ struct CallWorklet } }; -} // end anon namespace - -namespace vtkm -{ -namespace filter -{ - -//----------------------------------------------------------------------------- -inline VTKM_CONT Mask::Mask() - : vtkm::filter::FilterDataSet() - , Stride(1) - , CompactPoints(false) -{ -} - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT vtkm::cont::DataSet Mask::DoExecute(const vtkm::cont::DataSet& input, - vtkm::filter::PolicyBase policy) -{ - const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); - vtkm::cont::UnknownCellSet cellOut; - CallWorklet workletCaller(this->Stride, cellOut, this->Worklet); - vtkm::filter::ApplyPolicyCellSet(cells, policy, *this).CastAndCall(workletCaller); - - // create the output dataset - vtkm::cont::DataSet output; - output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); - output.SetCellSet(cellOut); - return output; -} - -//----------------------------------------------------------------------------- -template -inline VTKM_CONT bool Mask::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field, - vtkm::filter::PolicyBase) +VTKM_CONT bool DoMapField(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + const vtkm::worklet::Mask& worklet) { if (field.IsFieldPoint() || field.IsFieldGlobal()) { @@ -80,13 +44,41 @@ inline VTKM_CONT bool Mask::MapFieldOntoOutput(vtkm::cont::DataSet& result, } else if (field.IsFieldCell()) { - return vtkm::filter::MapFieldPermutation(field, this->Worklet.GetValidCellIds(), result); + return vtkm::filter::MapFieldPermutation(field, worklet.GetValidCellIds(), result); } else { return false; } } +} // end anon namespace + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ +//----------------------------------------------------------------------------- +VTKM_CONT vtkm::cont::DataSet Mask::DoExecute(const vtkm::cont::DataSet& input) +{ + const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); + vtkm::cont::UnknownCellSet cellOut; + vtkm::worklet::Mask worklet; + + CallWorklet workletCaller(this->Stride, cellOut, worklet); + cells.CastAndCallForTypes(workletCaller); + + // create the output dataset + vtkm::cont::DataSet output; + output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); + output.SetCellSet(cellOut); + + auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); }; + this->MapFieldsOntoOutput(input, output, mapper); + + return output; } -} -#endif +} // namespace entity_extraction +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/entity_extraction/Mask.h b/vtkm/filter/entity_extraction/Mask.h new file mode 100644 index 000000000..4611b0341 --- /dev/null +++ b/vtkm/filter/entity_extraction/Mask.h @@ -0,0 +1,53 @@ +//============================================================================ +// 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_filter_Mask_h +#define vtk_m_filter_Mask_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ +/// \brief Subselect cells using a stride +/// +/// Extract only every Nth cell where N is equal to a stride value +class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT Mask : public vtkm::filter::NewFilterField +{ +public: + // When CompactPoints is set, instead of copying the points and point fields + // from the input, the filter will create new compact fields without the unused elements + VTKM_CONT + bool GetCompactPoints() const { return this->CompactPoints; } + VTKM_CONT + void SetCompactPoints(bool value) { this->CompactPoints = value; } + + // Set the stride of the subsample + VTKM_CONT + vtkm::Id GetStride() const { return this->Stride; } + VTKM_CONT + void SetStride(vtkm::Id& stride) { this->Stride = stride; } + +private: + VTKM_CONT + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + vtkm::Id Stride = 1; + bool CompactPoints = false; +}; +} // namespace entity_extraction +} // namespace filter +} // namespace vtk + +#endif // vtk_m_filter_Mask_h diff --git a/vtkm/filter/entity_extraction/MaskPoints.cxx b/vtkm/filter/entity_extraction/MaskPoints.cxx index dd61fa211..20064efa3 100644 --- a/vtkm/filter/entity_extraction/MaskPoints.cxx +++ b/vtkm/filter/entity_extraction/MaskPoints.cxx @@ -12,49 +12,9 @@ #include #include -namespace vtkm +namespace { -namespace filter -{ -namespace entity_extraction -{ -//----------------------------------------------------------------------------- -VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute(const vtkm::cont::DataSet& input) -{ - // extract the input cell set - const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); - - // run the worklet on the cell set and input field - vtkm::cont::CellSetSingleType<> outCellSet; - vtkm::worklet::MaskPoints worklet; - - outCellSet = worklet.Run(cells, this->Stride); - - // create the output dataset - vtkm::cont::DataSet output; - output.SetCellSet(outCellSet); - output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); - - auto mapper = [&, this](auto& result, const auto& f) { this->MapFieldOntoOutput(result, f); }; - this->MapFieldsOntoOutput(input, output, mapper); - - // compact the unused points in the output dataset - if (this->CompactPoints) - { - vtkm::filter::clean_grid::CleanGrid compactor; - compactor.SetCompactPointFields(true); - compactor.SetMergePoints(false); - return compactor.Execute(output); - } - else - { - return output; - } -} - -//----------------------------------------------------------------------------- -VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) +bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::Field& field) { // point data is copied as is because it was not collapsed if (field.IsFieldPoint()) @@ -73,6 +33,49 @@ VTKM_CONT bool MaskPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result, return false; } } +} // anonymous namespace + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ + +//----------------------------------------------------------------------------- +VTKM_CONT vtkm::cont::DataSet MaskPoints::DoExecute(const vtkm::cont::DataSet& input) +{ + // extract the input cell set + const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); + + // run the worklet on the cell set and input field + vtkm::cont::CellSetSingleType<> outCellSet; + vtkm::worklet::MaskPoints worklet; + + outCellSet = worklet.Run(cells, this->Stride); + + // create the output dataset + vtkm::cont::DataSet output; + output.SetCellSet(outCellSet); + output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); + + auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f); }; + this->MapFieldsOntoOutput(input, output, mapper); + + // compact the unused points in the output dataset + if (this->CompactPoints) + { + vtkm::filter::clean_grid::CleanGrid compactor; + compactor.SetCompactPointFields(true); + compactor.SetMergePoints(false); + return compactor.Execute(output); + } + else + { + return output; + } +} + } // namespace entity_extraction } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/entity_extraction/MaskPoints.h b/vtkm/filter/entity_extraction/MaskPoints.h index 6c8520b2b..fd78043a6 100644 --- a/vtkm/filter/entity_extraction/MaskPoints.h +++ b/vtkm/filter/entity_extraction/MaskPoints.h @@ -42,8 +42,6 @@ private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field); - vtkm::Id Stride = 1; bool CompactPoints = true; }; diff --git a/vtkm/filter/entity_extraction/Threshold.cxx b/vtkm/filter/entity_extraction/Threshold.cxx new file mode 100644 index 000000000..7dbd1b7cd --- /dev/null +++ b/vtkm/filter/entity_extraction/Threshold.cxx @@ -0,0 +1,112 @@ +//============================================================================ +// 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 +{ +class ThresholdRange +{ +public: + VTKM_CONT + ThresholdRange(const vtkm::Float64& lower, const vtkm::Float64& upper) + : Lower(lower) + , Upper(upper) + { + } + + template + VTKM_EXEC bool operator()(const T& value) const + { + + return value >= static_cast(this->Lower) && value <= static_cast(this->Upper); + } + + //Needed to work with ArrayHandleVirtual + template + VTKM_EXEC bool operator()( + const vtkm::internal::ArrayPortalValueReference& value) const + { + using T = typename PortalType::ValueType; + return value.Get() >= static_cast(this->Lower) && value.Get() <= static_cast(this->Upper); + } + +private: + vtkm::Float64 Lower; + vtkm::Float64 Upper; +}; + +bool DoMapField(vtkm::cont::DataSet& result, + const vtkm::cont::Field& field, + const vtkm::worklet::Threshold& worklet) +{ + if (field.IsFieldPoint() || field.IsFieldGlobal()) + { + //we copy the input handle to the result dataset, reusing the metadata + result.AddField(field); + return true; + } + else if (field.IsFieldCell()) + { + return vtkm::filter::MapFieldPermutation(field, worklet.GetValidCellIds(), result); + } + else + { + return false; + } +} +} // end anon namespace + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ +//----------------------------------------------------------------------------- +vtkm::cont::DataSet Threshold::DoExecute(const vtkm::cont::DataSet& input) +{ + //get the cells and coordinates of the dataset + const vtkm::cont::UnknownCellSet& cells = input.GetCellSet(); + const auto& field = this->GetFieldFromDataSet(input); + + ThresholdRange predicate(this->GetLowerThreshold(), this->GetUpperThreshold()); + vtkm::worklet::Threshold worklet; + vtkm::cont::UnknownCellSet cellOut; + + auto ResolveArrayType = [&, this](const auto& concrete) { + // Note: there are two overloads of .Run, the first one taking an UncertainCellSet, which is + // the desired entry point in the following call. The other is a function template on the input + // CellSet. Without the call to .ResetCellSetList to turn an UnknownCellSet to an UncertainCellSet, + // the compiler will pick the function template (i.e. wrong overload). + cellOut = worklet.Run(cells.ResetCellSetList(), + concrete, + field.GetAssociation(), + predicate, + this->GetAllInRange()); + }; + + const auto& fieldArray = field.GetData(); + fieldArray.CastAndCallForTypes( + ResolveArrayType); + + vtkm::cont::DataSet output; + output.SetCellSet(cellOut); + output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); + + auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f, worklet); }; + this->MapFieldsOntoOutput(input, output, mapper); + + return output; +} +} // namespace entity_extraction +} // namespace filter +} // namespace vtkm diff --git a/vtkm/filter/entity_extraction/Threshold.h b/vtkm/filter/entity_extraction/Threshold.h new file mode 100644 index 000000000..e73392259 --- /dev/null +++ b/vtkm/filter/entity_extraction/Threshold.h @@ -0,0 +1,66 @@ +//============================================================================ +// 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_filter_entity_extraction_Threshold_h +#define vtk_m_filter_entity_extraction_Threshold_h + +#include +#include + +namespace vtkm +{ +namespace filter +{ +namespace entity_extraction +{ +/// \brief Extracts cells where scalar value in cell satisfies threshold criterion +/// +/// Extracts all cells from any dataset type that +/// satisfy a threshold criterion. A cell satisfies the criterion if the +/// scalar value of every point or cell satisfies the criterion. The +/// criterion takes the form of between two values. The output of this +/// filter is an permutation of the input dataset. +/// +/// You can threshold either on point or cell fields +class VTKM_FILTER_ENTITY_EXTRACTION_EXPORT Threshold : public vtkm::filter::NewFilterField +{ +public: + VTKM_CONT + void SetLowerThreshold(vtkm::Float64 value) { this->LowerValue = value; } + VTKM_CONT + void SetUpperThreshold(vtkm::Float64 value) { this->UpperValue = value; } + + VTKM_CONT + vtkm::Float64 GetLowerThreshold() const { return this->LowerValue; } + VTKM_CONT + vtkm::Float64 GetUpperThreshold() const { return this->UpperValue; } + + //If using scalars from point data, all scalars for all points in a cell must + //satisfy the threshold criterion if AllScalars is set. Otherwise, just a + //single scalar value satisfying the threshold criterion will extract the cell. + VTKM_CONT + void SetAllInRange(bool value) { this->ReturnAllInRange = value; } + + VTKM_CONT + bool GetAllInRange() const { return this->ReturnAllInRange; } + +private: + VTKM_CONT + vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; + + double LowerValue = 0; + double UpperValue = 0; + bool ReturnAllInRange = false; +}; +} // namespace entity_extraction +} // namespace filter +} // namespace vtkm + +#endif // vtk_m_filter_entity_extraction_Threshold_h diff --git a/vtkm/filter/entity_extraction/ThresholdPoints.cxx b/vtkm/filter/entity_extraction/ThresholdPoints.cxx index 8276ab98b..f04b40f3e 100644 --- a/vtkm/filter/entity_extraction/ThresholdPoints.cxx +++ b/vtkm/filter/entity_extraction/ThresholdPoints.cxx @@ -19,7 +19,7 @@ class ValuesBelow { public: VTKM_CONT - ValuesBelow(const vtkm::Float64& value) + explicit ValuesBelow(const vtkm::Float64& value) : Value(value) { } @@ -39,7 +39,7 @@ class ValuesAbove { public: VTKM_CONT - ValuesAbove(const vtkm::Float64& value) + explicit ValuesAbove(const vtkm::Float64& value) : Value(value) { } @@ -77,12 +77,34 @@ private: vtkm::Float64 Lower; vtkm::Float64 Upper; }; + +bool DoMapField(vtkm::cont::DataSet& result, const vtkm::cont::Field& field) +{ + // point data is copied as is because it was not collapsed + if (field.IsFieldPoint()) + { + result.AddField(field); + return true; + } + else if (field.IsFieldGlobal()) + { + result.AddField(field); + return true; + } + else + { + // cell data does not apply + return false; + } } +} // anonymous namespace + namespace vtkm { namespace filter { + namespace entity_extraction { //----------------------------------------------------------------------------- @@ -125,7 +147,7 @@ VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(const vtkm::cont::DataS vtkm::cont::CellSetSingleType<> outCellSet; vtkm::worklet::ThresholdPoints worklet; - auto ResolveType = [&, this](const auto& concrete) { + auto resolveType = [&, this](const auto& concrete) { switch (this->ThresholdType) { case THRESHOLD_BELOW: @@ -148,15 +170,14 @@ VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(const vtkm::cont::DataS } }; - const auto& fieldArray = field.GetData(); - fieldArray.CastAndCallForTypes(ResolveType); + this->CastAndCallScalarField(field, resolveType); // create the output dataset vtkm::cont::DataSet output; output.SetCellSet(outCellSet); output.AddCoordinateSystem(input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex())); - auto mapper = [&, this](auto& result, const auto& f) { this->MapFieldOntoOutput(result, f); }; + auto mapper = [&](auto& result, const auto& f) { DoMapField(result, f); }; this->MapFieldsOntoOutput(input, output, mapper); // compact the unused points in the output dataset @@ -173,27 +194,6 @@ VTKM_CONT vtkm::cont::DataSet ThresholdPoints::DoExecute(const vtkm::cont::DataS } } -//----------------------------------------------------------------------------- -VTKM_CONT bool ThresholdPoints::MapFieldOntoOutput(vtkm::cont::DataSet& result, - const vtkm::cont::Field& field) -{ - // point data is copied as is because it was not collapsed - if (field.IsFieldPoint()) - { - result.AddField(field); - return true; - } - else if (field.IsFieldGlobal()) - { - result.AddField(field); - return true; - } - else - { - // cell data does not apply - return false; - } -} } // namespace entity_extraction } // namespace filter } // namespace vtkm diff --git a/vtkm/filter/entity_extraction/ThresholdPoints.h b/vtkm/filter/entity_extraction/ThresholdPoints.h index 93de92a24..58ce00b47 100644 --- a/vtkm/filter/entity_extraction/ThresholdPoints.h +++ b/vtkm/filter/entity_extraction/ThresholdPoints.h @@ -41,18 +41,16 @@ public: void SetUpperThreshold(vtkm::Float64 value) { this->UpperValue = value; } VTKM_CONT - void SetThresholdBelow(const vtkm::Float64 value); + void SetThresholdBelow(vtkm::Float64 value); VTKM_CONT - void SetThresholdAbove(const vtkm::Float64 value); + void SetThresholdAbove(vtkm::Float64 value); VTKM_CONT - void SetThresholdBetween(const vtkm::Float64 value1, const vtkm::Float64 value2); + void SetThresholdBetween(vtkm::Float64 value1, vtkm::Float64 value2); private: VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; - VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field); - constexpr static int THRESHOLD_BELOW = 0; constexpr static int THRESHOLD_ABOVE = 1; constexpr static int THRESHOLD_BETWEEN = 2; diff --git a/vtkm/filter/entity_extraction/testing/CMakeLists.txt b/vtkm/filter/entity_extraction/testing/CMakeLists.txt index 60c6256c1..5f295de87 100644 --- a/vtkm/filter/entity_extraction/testing/CMakeLists.txt +++ b/vtkm/filter/entity_extraction/testing/CMakeLists.txt @@ -10,8 +10,13 @@ set(unit_tests UnitTestExternalFacesFilter.cxx + UnitTestExtractGeometryFilter.cxx UnitTestExtractPointsFilter.cxx + UnitTestExtractStructuredFilter.cxx + UnitTestGhostCellRemove.cxx + UnitTestMaskFilter.cxx UnitTestMaskPointsFilter.cxx + UnitTestThresholdFilter.cxx UnitTestThresholdPointsFilter.cxx ) diff --git a/vtkm/filter/testing/UnitTestExtractGeometryFilter.cxx b/vtkm/filter/entity_extraction/testing/UnitTestExtractGeometryFilter.cxx similarity index 93% rename from vtkm/filter/testing/UnitTestExtractGeometryFilter.cxx rename to vtkm/filter/entity_extraction/testing/UnitTestExtractGeometryFilter.cxx index 5ca1588aa..e2ecd88e2 100644 --- a/vtkm/filter/testing/UnitTestExtractGeometryFilter.cxx +++ b/vtkm/filter/entity_extraction/testing/UnitTestExtractGeometryFilter.cxx @@ -11,7 +11,7 @@ #include #include -#include +#include using vtkm::cont::testing::MakeTestDataSet; @@ -32,7 +32,7 @@ public: vtkm::Box box(minPoint, maxPoint); // Setup and run filter to extract by volume of interest - vtkm::filter::ExtractGeometry extractGeometry; + vtkm::filter::entity_extraction::ExtractGeometry extractGeometry; extractGeometry.SetImplicitFunction(box); extractGeometry.SetExtractInside(true); extractGeometry.SetExtractBoundaryCells(false); @@ -59,7 +59,7 @@ public: vtkm::Box box(minPoint, maxPoint); // Setup and run filter to extract by volume of interest - vtkm::filter::ExtractGeometry extractGeometry; + vtkm::filter::entity_extraction::ExtractGeometry extractGeometry; extractGeometry.SetImplicitFunction(box); extractGeometry.SetExtractInside(false); extractGeometry.SetExtractBoundaryCells(false); @@ -86,7 +86,7 @@ public: vtkm::Box box(minPoint, maxPoint); // Setup and run filter to extract by volume of interest - vtkm::filter::ExtractGeometry extractGeometry; + vtkm::filter::entity_extraction::ExtractGeometry extractGeometry; extractGeometry.SetImplicitFunction(box); extractGeometry.SetExtractInside(true); extractGeometry.SetExtractBoundaryCells(true); @@ -112,7 +112,7 @@ public: vtkm::Box box(minPoint, maxPoint); // Setup and run filter to extract by volume of interest - vtkm::filter::ExtractGeometry extractGeometry; + vtkm::filter::entity_extraction::ExtractGeometry extractGeometry; extractGeometry.SetImplicitFunction(box); extractGeometry.SetExtractInside(true); extractGeometry.SetExtractBoundaryCells(true); diff --git a/vtkm/filter/testing/UnitTestExtractStructuredFilter.cxx b/vtkm/filter/entity_extraction/testing/UnitTestExtractStructuredFilter.cxx similarity index 96% rename from vtkm/filter/testing/UnitTestExtractStructuredFilter.cxx rename to vtkm/filter/entity_extraction/testing/UnitTestExtractStructuredFilter.cxx index aeb37dc37..32f23ce55 100644 --- a/vtkm/filter/testing/UnitTestExtractStructuredFilter.cxx +++ b/vtkm/filter/entity_extraction/testing/UnitTestExtractStructuredFilter.cxx @@ -11,7 +11,7 @@ #include #include -#include +#include using vtkm::cont::testing::MakeTestDataSet; @@ -29,7 +29,7 @@ public: vtkm::RangeId3 range(1, 4, 1, 4, 0, 1); vtkm::Id3 sample(1, 1, 1); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; extract.SetVOI(range); extract.SetSampleRate(sample); @@ -63,7 +63,7 @@ public: std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // VOI within dataset extract.SetVOI(1, 4, 1, 4, 1, 4); @@ -99,7 +99,7 @@ public: std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // VOI surrounds dataset vtkm::Id3 minPoint(-1, -1, -1); @@ -136,7 +136,7 @@ public: { std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // VOI surrounds dataset vtkm::RangeId3 range(-1, 3, -1, 3, -1, 3); @@ -173,7 +173,7 @@ public: { std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 intersects dataset on far boundary vtkm::RangeId3 range(1, 8, 1, 8, 1, 8); @@ -211,7 +211,7 @@ public: std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 intersects dataset without corner vtkm::RangeId3 range(2, 8, 1, 4, 1, 4); @@ -249,7 +249,7 @@ public: std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 intersects dataset with plane vtkm::RangeId3 range(2, 8, 1, 2, 1, 4); @@ -287,7 +287,7 @@ public: std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 within data set with sampling vtkm::RangeId3 range(0, 5, 0, 5, 1, 4); @@ -325,7 +325,7 @@ public: std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 within data set with sampling vtkm::RangeId3 range(0, 5, 0, 5, 1, 4); @@ -361,7 +361,7 @@ public: { std::cout << "Testing extract structured uniform" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 within data set with sampling vtkm::RangeId3 range(0, 5, 0, 5, 1, 4); @@ -401,7 +401,7 @@ public: std::cout << "Testing extract structured rectilinear" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DRectilinearDataSet0(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 vtkm::RangeId3 range(0, 2, 0, 2, 0, 1); @@ -438,7 +438,7 @@ public: std::cout << "Testing extract structured rectilinear" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DRectilinearDataSet0(); - vtkm::filter::ExtractStructured extract; + vtkm::filter::entity_extraction::ExtractStructured extract; // RangeId3 and subsample vtkm::RangeId3 range(0, 2, 0, 2, 0, 2); diff --git a/vtkm/filter/testing/UnitTestGhostCellRemove.cxx b/vtkm/filter/entity_extraction/testing/UnitTestGhostCellRemove.cxx similarity index 83% rename from vtkm/filter/testing/UnitTestGhostCellRemove.cxx rename to vtkm/filter/entity_extraction/testing/UnitTestGhostCellRemove.cxx index 289fa29f4..f78cf073b 100644 --- a/vtkm/filter/testing/UnitTestGhostCellRemove.cxx +++ b/vtkm/filter/entity_extraction/testing/UnitTestGhostCellRemove.cxx @@ -14,16 +14,16 @@ #include #include -#include +#include namespace { -static vtkm::cont::ArrayHandle StructuredGhostCellArray(vtkm::Id nx, - vtkm::Id ny, - vtkm::Id nz, - int numLayers, - bool addMidGhost = false) +vtkm::cont::ArrayHandle StructuredGhostCellArray(vtkm::Id nx, + vtkm::Id ny, + vtkm::Id nz, + int numLayers, + bool addMidGhost = false) { vtkm::Id numCells = nx * ny; if (nz > 0) @@ -80,19 +80,18 @@ static vtkm::cont::ArrayHandle StructuredGhostCellArray(vtkm::Id nx return ghosts; } -static vtkm::cont::DataSet MakeUniform(vtkm::Id numI, - vtkm::Id numJ, - vtkm::Id numK, - int numLayers, - bool addMidGhost = false) +vtkm::cont::DataSet MakeUniform(vtkm::Id numI, + vtkm::Id numJ, + vtkm::Id numK, + int numLayers, + bool addMidGhost = false) { - vtkm::cont::DataSetBuilderUniform dsb; vtkm::cont::DataSet ds; if (numK == 0) - ds = dsb.Create(vtkm::Id2(numI + 1, numJ + 1)); + ds = vtkm::cont::DataSetBuilderUniform::Create(vtkm::Id2(numI + 1, numJ + 1)); else - ds = dsb.Create(vtkm::Id3(numI + 1, numJ + 1, numK + 1)); + ds = vtkm::cont::DataSetBuilderUniform::Create(vtkm::Id3(numI + 1, numJ + 1, numK + 1)); auto ghosts = StructuredGhostCellArray(numI, numJ, numK, numLayers, addMidGhost); ds.AddCellField("vtkmGhostCells", ghosts); @@ -100,13 +99,12 @@ static vtkm::cont::DataSet MakeUniform(vtkm::Id numI, return ds; } -static vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI, - vtkm::Id numJ, - vtkm::Id numK, - int numLayers, - bool addMidGhost = false) +vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI, + vtkm::Id numJ, + vtkm::Id numK, + int numLayers, + bool addMidGhost = false) { - vtkm::cont::DataSetBuilderRectilinear dsb; vtkm::cont::DataSet ds; std::size_t nx(static_cast(numI + 1)); std::size_t ny(static_cast(numJ + 1)); @@ -118,14 +116,14 @@ static vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI, y[i] = static_cast(i); if (numK == 0) - ds = dsb.Create(x, y); + ds = vtkm::cont::DataSetBuilderRectilinear::Create(x, y); else { std::size_t nz(static_cast(numK + 1)); std::vector z(nz); for (std::size_t i = 0; i < nz; i++) z[i] = static_cast(i); - ds = dsb.Create(x, y, z); + ds = vtkm::cont::DataSetBuilderRectilinear::Create(x, y, z); } auto ghosts = StructuredGhostCellArray(numI, numJ, numK, numLayers, addMidGhost); @@ -166,7 +164,7 @@ static void MakeExplicitCells(const CellSetType& cellSet, } } -static vtkm::cont::DataSet MakeExplicit(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK, int numLayers) +vtkm::cont::DataSet MakeExplicit(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK, int numLayers) { using CoordType = vtkm::Vec3f_32; @@ -187,21 +185,22 @@ static vtkm::cont::DataSet MakeExplicit(vtkm::Id numI, vtkm::Id numJ, vtkm::Id n vtkm::cont::ArrayHandle numIndices; vtkm::cont::ArrayHandle shapes; vtkm::cont::DataSet ds; - vtkm::cont::DataSetBuilderExplicit dsb; if (cellSet.IsType>()) { vtkm::Id2 dims(numI, numJ); MakeExplicitCells( cellSet.AsCellSet>(), dims, numIndices, shapes, conn); - ds = dsb.Create(explCoords, vtkm::CellShapeTagQuad(), 4, conn, "coordinates"); + ds = vtkm::cont::DataSetBuilderExplicit::Create( + explCoords, vtkm::CellShapeTagQuad(), 4, conn, "coordinates"); } else if (cellSet.IsType>()) { vtkm::Id3 dims(numI, numJ, numK); MakeExplicitCells( cellSet.AsCellSet>(), dims, numIndices, shapes, conn); - ds = dsb.Create(explCoords, vtkm::CellShapeTagHexahedron(), 8, conn, "coordinates"); + ds = vtkm::cont::DataSetBuilderExplicit::Create( + explCoords, vtkm::CellShapeTagHexahedron(), 8, conn, "coordinates"); } auto ghosts = StructuredGhostCellArray(numI, numJ, numK, numLayers); @@ -247,7 +246,7 @@ void TestGhostCellRemove() std::vector removeType = { "all", "byType" }; for (auto& rt : removeType) { - vtkm::filter::GhostCellRemove ghostCellRemoval; + vtkm::filter::entity_extraction::GhostCellRemove ghostCellRemoval; ghostCellRemoval.RemoveGhostField(); if (rt == "all") @@ -294,7 +293,7 @@ void TestGhostCellRemove() else if (dsType == "rectilinear") ds = MakeRectilinear(nx, ny, nz, layer, true); - vtkm::filter::GhostCellRemove ghostCellRemoval; + vtkm::filter::entity_extraction::GhostCellRemove ghostCellRemoval; ghostCellRemoval.RemoveGhostField(); auto output = ghostCellRemoval.Execute(ds); VTKM_TEST_ASSERT(output.GetCellSet().IsType>(), diff --git a/vtkm/filter/testing/UnitTestMaskFilter.cxx b/vtkm/filter/entity_extraction/testing/UnitTestMaskFilter.cxx similarity index 94% rename from vtkm/filter/testing/UnitTestMaskFilter.cxx rename to vtkm/filter/entity_extraction/testing/UnitTestMaskFilter.cxx index ac05c2850..ea4964e16 100644 --- a/vtkm/filter/testing/UnitTestMaskFilter.cxx +++ b/vtkm/filter/entity_extraction/testing/UnitTestMaskFilter.cxx @@ -11,7 +11,7 @@ #include #include -#include +#include using vtkm::cont::testing::MakeTestDataSet; @@ -27,7 +27,7 @@ public: vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet1(); // Setup and run filter to extract by stride - vtkm::filter::Mask mask; + vtkm::filter::entity_extraction::Mask mask; vtkm::Id stride = 2; mask.SetStride(stride); @@ -50,7 +50,7 @@ public: vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); // Setup and run filter to extract by stride - vtkm::filter::Mask mask; + vtkm::filter::entity_extraction::Mask mask; vtkm::Id stride = 9; mask.SetStride(stride); @@ -71,7 +71,7 @@ public: vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5(); // Setup and run filter to extract by stride - vtkm::filter::Mask mask; + vtkm::filter::entity_extraction::Mask mask; vtkm::Id stride = 2; mask.SetStride(stride); diff --git a/vtkm/filter/testing/UnitTestThresholdFilter.cxx b/vtkm/filter/entity_extraction/testing/UnitTestThresholdFilter.cxx similarity index 96% rename from vtkm/filter/testing/UnitTestThresholdFilter.cxx rename to vtkm/filter/entity_extraction/testing/UnitTestThresholdFilter.cxx index 5b091a821..09b509407 100644 --- a/vtkm/filter/testing/UnitTestThresholdFilter.cxx +++ b/vtkm/filter/entity_extraction/testing/UnitTestThresholdFilter.cxx @@ -10,8 +10,8 @@ #include #include -#include #include +#include using vtkm::cont::testing::MakeTestDataSet; @@ -24,7 +24,7 @@ public: void TestRegular2D(bool returnAllInRange) const { vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet0(); - vtkm::filter::Threshold threshold; + vtkm::filter::entity_extraction::Threshold threshold; if (returnAllInRange) { @@ -80,7 +80,7 @@ public: void TestRegular3D(bool returnAllInRange) const { vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet0(); - vtkm::filter::Threshold threshold; + vtkm::filter::entity_extraction::Threshold threshold; if (returnAllInRange) { @@ -141,7 +141,7 @@ public: std::cout << "Testing threshold on 3D explicit dataset" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet1(); - vtkm::filter::Threshold threshold; + vtkm::filter::entity_extraction::Threshold threshold; threshold.SetLowerThreshold(20); threshold.SetUpperThreshold(21); @@ -171,7 +171,7 @@ public: std::cout << "Testing threshold on 3D explicit dataset with empty results" << std::endl; vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet1(); - vtkm::filter::Threshold threshold; + vtkm::filter::entity_extraction::Threshold threshold; threshold.SetLowerThreshold(500); threshold.SetUpperThreshold(500.1); diff --git a/vtkm/filter/entity_extraction/worklet/CMakeLists.txt b/vtkm/filter/entity_extraction/worklet/CMakeLists.txt index c3f664974..b53737f73 100644 --- a/vtkm/filter/entity_extraction/worklet/CMakeLists.txt +++ b/vtkm/filter/entity_extraction/worklet/CMakeLists.txt @@ -10,8 +10,12 @@ set(headers ExternalFaces.h + ExtractGeometry.h + ExtractStructured.h ExtractPoints.h + Mask.h MaskPoints.h + Threshold.h ThresholdPoints.h ) diff --git a/vtkm/filter/entity_extraction/worklet/ExternalFaces.h b/vtkm/filter/entity_extraction/worklet/ExternalFaces.h index 3b52b9325..d3a872373 100644 --- a/vtkm/filter/entity_extraction/worklet/ExternalFaces.h +++ b/vtkm/filter/entity_extraction/worklet/ExternalFaces.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -940,7 +941,9 @@ public: auto offsetsArray = vtkm::cont::make_ArrayHandleConcatenate(faceOffsetsTrim, adjustedPolyDataOffsets); OffsetsArrayType joinedOffsets; - vtkm::cont::ArrayCopy(offsetsArray, joinedOffsets); + // Need to compile a special device copy because the precompiled ArrayCopy does not + // know how to copy the ArrayHandleTransform. + vtkm::cont::ArrayCopyDevice(offsetsArray, joinedOffsets); vtkm::cont::ArrayHandleConcatenate, vtkm::cont::ArrayHandle> diff --git a/vtkm/worklet/ExtractGeometry.h b/vtkm/filter/entity_extraction/worklet/ExtractGeometry.h similarity index 96% rename from vtkm/worklet/ExtractGeometry.h rename to vtkm/filter/entity_extraction/worklet/ExtractGeometry.h index 8b3ec2728..17679bdf9 100644 --- a/vtkm/worklet/ExtractGeometry.h +++ b/vtkm/filter/entity_extraction/worklet/ExtractGeometry.h @@ -10,7 +10,6 @@ #ifndef vtkm_m_worklet_ExtractGeometry_h #define vtkm_m_worklet_ExtractGeometry_h -#include #include #include @@ -18,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -144,8 +143,8 @@ public: vtkm::cont::ArrayHandle passFlags; ExtractCellsByVOI worklet(extractInside, extractBoundaryCells, extractOnlyBoundaryCells); - DispatcherMapTopology dispatcher(worklet); - dispatcher.Invoke(cellSet, coordinates, implicitFunction, passFlags); + vtkm::cont::Invoker invoke; + invoke(worklet, cellSet, coordinates, implicitFunction, passFlags); vtkm::cont::ArrayHandleCounting indices = vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), vtkm::Id(1), passFlags.GetNumberOfValues()); diff --git a/vtkm/filter/entity_extraction/worklet/ExtractPoints.h b/vtkm/filter/entity_extraction/worklet/ExtractPoints.h index 9fab54962..ea1ea85b1 100644 --- a/vtkm/filter/entity_extraction/worklet/ExtractPoints.h +++ b/vtkm/filter/entity_extraction/worklet/ExtractPoints.h @@ -10,17 +10,16 @@ #ifndef vtkm_m_worklet_ExtractPoints_h #define vtkm_m_worklet_ExtractPoints_h -#include -#include - #include #include #include #include -#include +#include #include +#include + namespace vtkm { namespace worklet @@ -41,7 +40,7 @@ public: using ExecutionSignature = _4(_2, _3); VTKM_CONT - ExtractPointsByVOI(bool extractInside) + explicit ExtractPointsByVOI(bool extractInside) : passValue(extractInside) , failValue(!extractInside) { @@ -93,8 +92,8 @@ public: vtkm::cont::ArrayHandle passFlags; ExtractPointsByVOI worklet(extractInside); - DispatcherMapTopology dispatcher(worklet); - dispatcher.Invoke(cellSet, coordinates, implicitFunction, passFlags); + vtkm::cont::Invoker invoke; + invoke(worklet, cellSet, coordinates, implicitFunction, passFlags); vtkm::cont::ArrayHandleCounting indices = vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), vtkm::Id(1), passFlags.GetNumberOfValues()); diff --git a/vtkm/worklet/ExtractStructured.h b/vtkm/filter/entity_extraction/worklet/ExtractStructured.h similarity index 98% rename from vtkm/worklet/ExtractStructured.h rename to vtkm/filter/entity_extraction/worklet/ExtractStructured.h index 09b4051f4..f38e0d497 100644 --- a/vtkm/worklet/ExtractStructured.h +++ b/vtkm/filter/entity_extraction/worklet/ExtractStructured.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,7 @@ struct ExtractCopy : public vtkm::worklet::WorkletMapField { using ControlSignature = void(FieldIn, FieldOut, WholeArrayIn); - ExtractCopy(const vtkm::Id3& dim) + explicit ExtractCopy(const vtkm::Id3& dim) : XDim(dim[0]) , XYDim(dim[0] * dim[1]) { @@ -178,7 +179,7 @@ private: return outCs; } default: - return UncertainCellSetStructured(); + return {}; } } @@ -438,7 +439,7 @@ private: inOrigin[2] + static_cast(this->VOI.Z.Min) * inSpacing[2]); CoordType outSpacing = inSpacing * static_cast(this->SampleRate); - return CoordsArray(this->OutputDimensions, outOrigin, outSpacing); + return { this->OutputDimensions, outOrigin, outSpacing }; } RectilinearCoordinatesArrayHandle MapCoordinatesRectilinear( @@ -522,8 +523,8 @@ public: result.Allocate(this->ValidPoints.GetNumberOfValues()); ExtractCopy worklet(this->InputDimensions); - DispatcherMapField dispatcher(worklet); - dispatcher.Invoke(this->ValidPoints, result, field); + vtkm::cont::Invoker invoke; + invoke(worklet, this->ValidPoints, result, field); return result; } @@ -538,8 +539,8 @@ public: auto inputCellDimensions = this->InputDimensions - vtkm::Id3(1); ExtractCopy worklet(inputCellDimensions); - DispatcherMapField dispatcher(worklet); - dispatcher.Invoke(this->ValidCells, result, field); + vtkm::cont::Invoker invoke; + invoke(worklet, this->ValidCells, result, field); return result; } diff --git a/vtkm/worklet/Mask.h b/vtkm/filter/entity_extraction/worklet/Mask.h similarity index 96% rename from vtkm/worklet/Mask.h rename to vtkm/filter/entity_extraction/worklet/Mask.h index a41b15563..b96efab9d 100644 --- a/vtkm/worklet/Mask.h +++ b/vtkm/filter/entity_extraction/worklet/Mask.h @@ -10,7 +10,6 @@ #ifndef vtkm_m_worklet_Mask_h #define vtkm_m_worklet_Mask_h -#include #include #include @@ -18,7 +17,6 @@ #include #include #include -#include namespace vtkm { diff --git a/vtkm/filter/entity_extraction/worklet/MaskPoints.h b/vtkm/filter/entity_extraction/worklet/MaskPoints.h index 5eb60d7c0..ed060c32a 100644 --- a/vtkm/filter/entity_extraction/worklet/MaskPoints.h +++ b/vtkm/filter/entity_extraction/worklet/MaskPoints.h @@ -13,7 +13,6 @@ #include #include #include -#include namespace vtkm { diff --git a/vtkm/worklet/Threshold.h b/vtkm/filter/entity_extraction/worklet/Threshold.h similarity index 98% rename from vtkm/worklet/Threshold.h rename to vtkm/filter/entity_extraction/worklet/Threshold.h index dffb29e4a..d8ab6c3cd 100644 --- a/vtkm/worklet/Threshold.h +++ b/vtkm/filter/entity_extraction/worklet/Threshold.h @@ -15,10 +15,8 @@ #include #include -#include #include #include -#include #include #include #include diff --git a/vtkm/filter/entity_extraction/worklet/ThresholdPoints.h b/vtkm/filter/entity_extraction/worklet/ThresholdPoints.h index 4bc20eb9e..ece19b4cb 100644 --- a/vtkm/filter/entity_extraction/worklet/ThresholdPoints.h +++ b/vtkm/filter/entity_extraction/worklet/ThresholdPoints.h @@ -10,12 +10,11 @@ #ifndef vtkm_m_worklet_ThresholdPoints_h #define vtkm_m_worklet_ThresholdPoints_h -#include -#include - #include #include -#include +#include + +#include namespace vtkm { @@ -64,8 +63,8 @@ public: using ThresholdWorklet = ThresholdPointField; ThresholdWorklet worklet(predicate); - DispatcherMapTopology dispatcher(worklet); - dispatcher.Invoke(cellSet, scalars, passFlags); + vtkm::cont::Invoker invoker; + invoker(worklet, cellSet, scalars, passFlags); vtkm::cont::ArrayHandle pointIds; vtkm::cont::ArrayHandleCounting indices = diff --git a/vtkm/filter/field_transform/CMakeLists.txt b/vtkm/filter/field_transform/CMakeLists.txt index e488a2421..58a39d054 100644 --- a/vtkm/filter/field_transform/CMakeLists.txt +++ b/vtkm/filter/field_transform/CMakeLists.txt @@ -9,13 +9,13 @@ ##============================================================================ set(field_transform_headers GenerateIds.h) -set(field_transform_sources_device +set(field_transform_sources GenerateIds.cxx) vtkm_library( NAME vtkm_filter_field_transform HEADERS ${field_transform_headers} - DEVICE_SOURCES ${field_transform_sources_device} + SOURCES ${field_transform_sources} USE_VTKM_JOB_POOL ) diff --git a/vtkm/filter/testing/CMakeLists.txt b/vtkm/filter/testing/CMakeLists.txt index 82407349a..769e80151 100644 --- a/vtkm/filter/testing/CMakeLists.txt +++ b/vtkm/filter/testing/CMakeLists.txt @@ -15,39 +15,26 @@ set(headers set(unit_tests UnitTestCellAverageFilter.cxx UnitTestCellMeasuresFilter.cxx - UnitTestCellSetConnectivityFilter.cxx UnitTestContourTreeUniformFilter.cxx UnitTestContourTreeUniformAugmentedFilter.cxx UnitTestContourTreeUniformDistributedFilter.cxx UnitTestCoordinateSystemTransform.cxx - UnitTestCrossProductFilter.cxx - UnitTestEntropyFilter.cxx - UnitTestExtractGeometryFilter.cxx - UnitTestExtractStructuredFilter.cxx UnitTestFieldMetadata.cxx UnitTestFieldSelection.cxx UnitTestFieldToColors.cxx UnitTestGradientExplicit.cxx UnitTestGradientUniform.cxx UnitTestGhostCellClassify.cxx - UnitTestGhostCellRemove.cxx - UnitTestHistogramFilter.cxx - UnitTestImageConnectivityFilter.cxx UnitTestImageDifferenceFilter.cxx UnitTestImageMedianFilter.cxx UnitTestLagrangianFilter.cxx UnitTestLagrangianStructuresFilter.cxx UnitTestMapFieldMergeAverage.cxx UnitTestMapFieldPermutation.cxx - UnitTestMaskFilter.cxx UnitTestMeshQualityFilter.cxx UnitTestMIRFilter.cxx UnitTestMultiBlockFilter.cxx - UnitTestNDEntropyFilter.cxx - UnitTestNDHistogramFilter.cxx - UnitTestParticleDensity.cxx UnitTestPartitionedDataSetFilters.cxx - UnitTestPartitionedDataSetHistogramFilter.cxx UnitTestPointAverageFilter.cxx UnitTestPointAverageCellSetExtrude.cxx UnitTestPointElevationFilter.cxx @@ -58,7 +45,6 @@ set(unit_tests UnitTestStreamSurfaceFilter.cxx UnitTestSurfaceNormalsFilter.cxx UnitTestTetrahedralizeFilter.cxx - UnitTestThresholdFilter.cxx UnitTestTriangulateFilter.cxx UnitTestTubeFilter.cxx UnitTestVectorMagnitudeFilter.cxx diff --git a/vtkm/filter/testing/RenderTestAmrArrays.cxx b/vtkm/filter/testing/RenderTestAmrArrays.cxx index 446f158d8..21802b714 100644 --- a/vtkm/filter/testing/RenderTestAmrArrays.cxx +++ b/vtkm/filter/testing/RenderTestAmrArrays.cxx @@ -9,8 +9,8 @@ //============================================================================ #include -#include #include +#include #include #include @@ -30,7 +30,7 @@ void TestAmrArraysExecute(int dim, int numberOfLevels, int cellsPerDimension) // amrDataSet.PrintSummary(std::cout); // Remove blanked cells - vtkm::filter::Threshold threshold; + vtkm::filter::entity_extraction::Threshold threshold; threshold.SetLowerThreshold(0); threshold.SetUpperThreshold(1); threshold.SetActiveField("vtkGhostType"); diff --git a/vtkm/filter/vector_calculus/CMakeLists.txt b/vtkm/filter/vector_calculus/CMakeLists.txt index ad82b3169..8f0f68fe2 100644 --- a/vtkm/filter/vector_calculus/CMakeLists.txt +++ b/vtkm/filter/vector_calculus/CMakeLists.txt @@ -8,9 +8,13 @@ ## PURPOSE. See the above copyright notice for more information. ##============================================================================ set(vector_calculus_headers - DotProduct.h) + CrossProduct.h + DotProduct.h + ) set(vector_calculus_sources_device - DotProduct.cxx) + CrossProduct.cxx + DotProduct.cxx + ) vtkm_library( NAME vtkm_filter_vector_calculus diff --git a/vtkm/filter/vector_calculus/CrossProduct.cxx b/vtkm/filter/vector_calculus/CrossProduct.cxx new file mode 100644 index 000000000..cb66d65d6 --- /dev/null +++ b/vtkm/filter/vector_calculus/CrossProduct.cxx @@ -0,0 +1,91 @@ +//============================================================================ +// 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 +{ + +class CrossProductWorklet : public vtkm::worklet::WorkletMapField +{ +public: + using ControlSignature = void(FieldIn, FieldIn, FieldOut); + + template + VTKM_EXEC void operator()(const vtkm::Vec& vec1, + const vtkm::Vec& vec2, + vtkm::Vec& outVec) const + { + outVec = vtkm::Cross(vec1, vec2); + } +}; + +} // anonymous namespace + +namespace vtkm +{ +namespace filter +{ +namespace vector_calculus +{ + +//----------------------------------------------------------------------------- +VTKM_CONT CrossProduct::CrossProduct() +{ + this->SetOutputFieldName("crossproduct"); +} + +//----------------------------------------------------------------------------- +VTKM_CONT vtkm::cont::DataSet CrossProduct::DoExecute(const vtkm::cont::DataSet& inDataSet) +{ + vtkm::cont::Field primaryField = this->GetFieldFromDataSet(0, inDataSet); + vtkm::cont::UnknownArrayHandle primaryArray = primaryField.GetData(); + + vtkm::cont::UnknownArrayHandle outArray; + + // We are using a C++14 auto lambda here. The advantage over a Functor is obvious, we don't + // need to explicitly pass filter, input/output DataSets etc. thus reduce the impact to + // the legacy code. The lambda can also access the private part of the filter thus reducing + // filter's public interface profile. CastAndCall tries to cast primaryArray of unknown value + // type and storage to a concrete ArrayHandle with T from the `TypeList` and S from + // `StorageList`. It then passes the concrete array to the lambda as the first argument. + // We can later recover the concrete ValueType, T, from the concrete array. + auto resolveType = [&, this](const auto& concrete) { + // use std::decay to remove const ref from the decltype of concrete. + using T = typename std::decay_t::ValueType; + const auto& secondaryField = this->GetFieldFromDataSet(1, inDataSet); + vtkm::cont::ArrayHandle secondaryArray; + vtkm::cont::ArrayCopyShallowIfPossible(secondaryField.GetData(), secondaryArray); + + vtkm::cont::ArrayHandle result; + this->Invoke(CrossProductWorklet{}, concrete, secondaryArray, result); + outArray = result; + }; + + this->CastAndCallVecField<3>(primaryArray, resolveType); + + vtkm::cont::DataSet outDataSet; + outDataSet.CopyStructure(inDataSet); + outDataSet.AddField({ this->GetOutputFieldName(), primaryField.GetAssociation(), outArray }); + + this->MapFieldsOntoOutput(inDataSet, outDataSet); + + return outDataSet; +} + +} +} +} // namespace vtkm::filter::vector_calculus diff --git a/vtkm/filter/vector_calculus/CrossProduct.h b/vtkm/filter/vector_calculus/CrossProduct.h new file mode 100644 index 000000000..a286d25c7 --- /dev/null +++ b/vtkm/filter/vector_calculus/CrossProduct.h @@ -0,0 +1,129 @@ +//============================================================================ +// 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_filter_vector_calculus_CrossProduct_h +#define vtk_m_filter_vector_calculus_CrossProduct_h + +#include + +#include + +namespace vtkm +{ +namespace filter +{ +namespace vector_calculus +{ + +class VTKM_FILTER_VECTOR_CALCULUS_EXPORT CrossProduct : public vtkm::filter::NewFilterField +{ +public: + VTKM_CONT + CrossProduct(); + + //@{ + /// Choose the primary field to operate on. In the cross product operation A x B, A is + /// the primary field. + VTKM_CONT + void SetPrimaryField( + const std::string& name, + vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) + { + this->SetActiveField(name, association); + } + + VTKM_CONT const std::string& GetPrimaryFieldName() const { return this->GetActiveFieldName(); } + VTKM_CONT vtkm::cont::Field::Association GetPrimaryFieldAssociation() const + { + return this->GetActiveFieldAssociation(); + } + //@} + + //@{ + /// When set to true, uses a coordinate system as the primary field instead of the one selected + /// by name. Use SetPrimaryCoordinateSystem to select which coordinate system. + VTKM_CONT + void SetUseCoordinateSystemAsPrimaryField(bool flag) + { + this->SetUseCoordinateSystemAsField(flag); + } + VTKM_CONT + bool GetUseCoordinateSystemAsPrimaryField() const + { + return this->GetUseCoordinateSystemAsField(); + } + //@} + + //@{ + /// Select the coordinate system index to use as the primary field. This only has an effect when + /// UseCoordinateSystemAsPrimaryField is true. + VTKM_CONT + void SetPrimaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(index); } + VTKM_CONT + vtkm::Id GetPrimaryCoordinateSystemIndex() const + { + return this->GetActiveCoordinateSystemIndex(); + } + //@} + + //@{ + /// Choose the secondary field to operate on. In the dot product operation A . B, B is + /// the secondary field. + VTKM_CONT + void SetSecondaryField( + const std::string& name, + vtkm::cont::Field::Association association = vtkm::cont::Field::Association::ANY) + { + this->SetActiveField(1, name, association); + } + + VTKM_CONT const std::string& GetSecondaryFieldName() const { return this->GetActiveFieldName(1); } + VTKM_CONT vtkm::cont::Field::Association GetSecondaryFieldAssociation() const + { + return this->GetActiveFieldAssociation(1); + } + //@} + + //@{ + /// When set to true, uses a coordinate system as the secondary field instead of the one selected + /// by name. Use SetSecondaryCoordinateSystem to select which coordinate system. + VTKM_CONT + void SetUseCoordinateSystemAsSecondaryField(bool flag) + { + this->SetUseCoordinateSystemAsField(1, flag); + } + VTKM_CONT + bool GetUseCoordinateSystemAsSecondaryField() const + { + return this->GetUseCoordinateSystemAsField(1); + } + //@} + + //@{ + /// Select the coordinate system index to use as the secondary field. This only has an effect when + /// UseCoordinateSystemAsSecondaryField is true. + VTKM_CONT + void SetSecondaryCoordinateSystem(vtkm::Id index) { this->SetActiveCoordinateSystem(1, index); } + VTKM_CONT + vtkm::Id GetSecondaryCoordinateSystemIndex() const + { + return this->GetActiveCoordinateSystemIndex(1); + } + //@} + +private: + VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override; +}; + +} +} +} // namespace vtkm::filter::vector_calculus + +#endif // vtk_m_filter_vector_calculus_CrossProduct_h diff --git a/vtkm/filter/vector_calculus/DotProduct.cxx b/vtkm/filter/vector_calculus/DotProduct.cxx index 32f393b30..72329c3a8 100644 --- a/vtkm/filter/vector_calculus/DotProduct.cxx +++ b/vtkm/filter/vector_calculus/DotProduct.cxx @@ -8,33 +8,59 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ +#include #include #include namespace // anonymous namespace making worklet::DotProduct internal to this .cxx { -namespace worklet + +struct DotProductWorklet : vtkm::worklet::WorkletMapField { -class DotProduct : public vtkm::worklet::WorkletMapField -{ -public: using ControlSignature = void(FieldIn, FieldIn, FieldOut); - template - VTKM_EXEC void operator()(const vtkm::Vec& v1, - const vtkm::Vec& v2, - T& outValue) const + template + VTKM_EXEC void operator()(const T1& v1, const T2& v2, T3& outValue) const { - outValue = static_cast(vtkm::Dot(v1, v2)); - } - - template - VTKM_EXEC void operator()(T s1, T s2, T& outValue) const - { - outValue = static_cast(s1 * s2); + VTKM_ASSERT(v1.GetNumberOfComponents() == v2.GetNumberOfComponents()); + outValue = v1[0] * v2[0]; + for (vtkm::IdComponent i = 1; i < v1.GetNumberOfComponents(); ++i) + { + outValue += v1[i] * v2[i]; + } } }; -} // namespace worklet + +template +vtkm::cont::UnknownArrayHandle DoDotProduct(const PrimaryArrayType& primaryArray, + const vtkm::cont::Field& secondaryField) +{ + using T = typename PrimaryArrayType::ValueType::ComponentType; + + vtkm::cont::Invoker invoke; + vtkm::cont::ArrayHandle outputArray; + + if (secondaryField.GetData().IsBaseComponentType()) + { + invoke(DotProductWorklet{}, + primaryArray, + secondaryField.GetData().ExtractArrayFromComponents(), + outputArray); + } + else + { + // Data types of primary and secondary array do not match. Rather than try to replicate every + // possibility, get the secondary array as a FloatDefault. + vtkm::cont::UnknownArrayHandle castSecondaryArray = secondaryField.GetDataAsDefaultFloat(); + invoke(DotProductWorklet{}, + primaryArray, + castSecondaryArray.ExtractArrayFromComponents(), + outputArray); + } + + return outputArray; +} + } // anonymous namespace namespace vtkm @@ -51,37 +77,39 @@ VTKM_CONT DotProduct::DotProduct() VTKM_CONT vtkm::cont::DataSet DotProduct::DoExecute(const vtkm::cont::DataSet& inDataSet) { - const auto& primaryArray = this->GetFieldFromDataSet(inDataSet).GetData(); + vtkm::cont::Field primaryField = this->GetFieldFromDataSet(0, inDataSet); + vtkm::cont::UnknownArrayHandle primaryArray = primaryField.GetData(); + + vtkm::cont::Field secondaryField = this->GetFieldFromDataSet(1, inDataSet); + + if (primaryArray.GetNumberOfComponentsFlat() != + secondaryField.GetData().GetNumberOfComponentsFlat()) + { + throw vtkm::cont::ErrorFilterExecution( + "Primary and secondary arrays of DotProduct filter have different number of components."); + } vtkm::cont::UnknownArrayHandle outArray; - // We are using a C++14 auto lambda here. The advantage over a Functor is obvious, we don't - // need to explicitly pass filter, input/output DataSets etc. thus reduce the impact to - // the legacy code. The lambda can also access the private part of the filter thus reducing - // filter's public interface profile. CastAndCall tries to cast primaryArray of unknown value - // type and storage to a concrete ArrayHandle with T from the `TypeList` and S from - // `StorageList`. It then passes the concrete array to the lambda as the first argument. - // We can later recover the concrete ValueType, T, from the concrete array. - auto ResolveType = [&, this](const auto& concrete) { - // use std::decay to remove const ref from the decltype of concrete. - using T = typename std::decay_t::ValueType; - const auto& secondaryField = this->GetFieldFromDataSet(1, inDataSet); - vtkm::cont::UnknownArrayHandle secondary = vtkm::cont::ArrayHandle{}; - secondary.CopyShallowIfPossible(secondaryField.GetData()); + if (primaryArray.IsBaseComponentType()) + { + outArray = + DoDotProduct(primaryArray.ExtractArrayFromComponents(), secondaryField); + } + else if (primaryArray.IsBaseComponentType()) + { + outArray = + DoDotProduct(primaryArray.ExtractArrayFromComponents(), secondaryField); + } + else + { + primaryArray = primaryField.GetDataAsDefaultFloat(); + outArray = + DoDotProduct(primaryArray.ExtractArrayFromComponents(), secondaryField); + } - vtkm::cont::ArrayHandle::ComponentType> result; - this->Invoke(::worklet::DotProduct{}, - concrete, - secondary.template AsArrayHandle>(), - result); - outArray = result; - }; - - primaryArray - .CastAndCallForTypesWithFloatFallback( - ResolveType); - - vtkm::cont::DataSet outDataSet = inDataSet; // copy + vtkm::cont::DataSet outDataSet; + outDataSet.CopyStructure(inDataSet); outDataSet.AddField({ this->GetOutputFieldName(), this->GetFieldFromDataSet(inDataSet).GetAssociation(), outArray }); diff --git a/vtkm/filter/vector_calculus/testing/CMakeLists.txt b/vtkm/filter/vector_calculus/testing/CMakeLists.txt index 6b2b7c122..f1f3223ff 100644 --- a/vtkm/filter/vector_calculus/testing/CMakeLists.txt +++ b/vtkm/filter/vector_calculus/testing/CMakeLists.txt @@ -9,6 +9,7 @@ ##============================================================================ set(unit_tests + UnitTestCrossProductFilter.cxx UnitTestDotProductFilter.cxx ) diff --git a/vtkm/filter/testing/UnitTestCrossProductFilter.cxx b/vtkm/filter/vector_calculus/testing/UnitTestCrossProductFilter.cxx similarity index 96% rename from vtkm/filter/testing/UnitTestCrossProductFilter.cxx rename to vtkm/filter/vector_calculus/testing/UnitTestCrossProductFilter.cxx index 6c7cef858..48a88766e 100644 --- a/vtkm/filter/testing/UnitTestCrossProductFilter.cxx +++ b/vtkm/filter/vector_calculus/testing/UnitTestCrossProductFilter.cxx @@ -10,7 +10,9 @@ #include #include -#include +#include + +#include #include #include @@ -139,7 +141,7 @@ void TestCrossProduct() { std::cout << " Both vectors as normal fields" << std::endl; - vtkm::filter::CrossProduct filter; + vtkm::filter::vector_calculus::CrossProduct filter; filter.SetPrimaryField("vec1"); filter.SetSecondaryField("vec2", vtkm::cont::Field::Association::POINTS); @@ -163,7 +165,7 @@ void TestCrossProduct() { std::cout << " First field as coordinates" << std::endl; - vtkm::filter::CrossProduct filter; + vtkm::filter::vector_calculus::CrossProduct filter; filter.SetUseCoordinateSystemAsPrimaryField(true); filter.SetPrimaryCoordinateSystem(1); filter.SetSecondaryField("vec2"); @@ -184,7 +186,7 @@ void TestCrossProduct() { std::cout << " Second field as coordinates" << std::endl; - vtkm::filter::CrossProduct filter; + vtkm::filter::vector_calculus::CrossProduct filter; filter.SetPrimaryField("vec1"); filter.SetUseCoordinateSystemAsSecondaryField(true); filter.SetSecondaryCoordinateSystem(2); diff --git a/vtkm/internal/Configure.h.in b/vtkm/internal/Configure.h.in index 9f0f66ac0..d75c2d5fa 100644 --- a/vtkm/internal/Configure.h.in +++ b/vtkm/internal/Configure.h.in @@ -49,6 +49,11 @@ //compliance #define VTKM_CLANG +#elif defined(__MINGW32__) +//Check for MinGW before GCC, since MinGW will be otherwise categorized +//as VTKM_GCC +#define VTKM_MINGW + #elif defined(__GNUC__) // Several compilers pretend to be GCC but have minor differences. Try to // compensate for that, by checking for those compilers first diff --git a/vtkm/io/CMakeLists.txt b/vtkm/io/CMakeLists.txt index 758350de9..88016c537 100644 --- a/vtkm/io/CMakeLists.txt +++ b/vtkm/io/CMakeLists.txt @@ -49,19 +49,15 @@ set(sources ImageWriterPNG.cxx ImageWriterPNM.cxx VTKDataSetReader.cxx + VTKDataSetReaderBase.cxx VTKDataSetWriter.cxx VTKPolyDataReader.cxx + VTKRectilinearGridReader.cxx VTKStructuredGridReader.cxx VTKStructuredPointsReader.cxx VTKUnstructuredGridReader.cxx ) -# These files use ArrayCopy which uses a WorkletMapField thus are required to be device_sources -set(device_sources - VTKDataSetReaderBase.cxx - VTKRectilinearGridReader.cxx - ) - if (VTKm_ENABLE_HDF5_IO) set(headers ${headers} diff --git a/vtkm/io/FileUtils.cxx b/vtkm/io/FileUtils.cxx index e8c1785e4..7c252fa5e 100644 --- a/vtkm/io/FileUtils.cxx +++ b/vtkm/io/FileUtils.cxx @@ -17,7 +17,7 @@ #include #include -#ifdef _MSC_VER +#ifdef _WIN32 #include #endif @@ -42,7 +42,7 @@ std::string Filename(const std::string& filePath) // std::filesystem::path path(filePath); // return path.filename(); -#ifdef _MSC_VER +#ifdef _WIN32 auto lastSlashPos = filePath.rfind(GetWindowsPathSeperator(filePath)); #else auto lastSlashPos = filePath.rfind('/'); @@ -60,7 +60,7 @@ std::string ParentPath(const std::string& filePath) // std::filesystem::path path(filePath); // return path.parent_path(); -#ifdef _MSC_VER +#ifdef _WIN32 auto lastSlashPos = filePath.rfind(GetWindowsPathSeperator(filePath)); #else auto lastSlashPos = filePath.rfind('/'); @@ -88,7 +88,7 @@ bool CreateDirectoriesFromFilePath(const std::string& filePath) return false; } -#ifdef _MSC_VER +#ifdef _WIN32 auto ret = _mkdir(dir.c_str()); #else mode_t mode = 0755; @@ -145,7 +145,7 @@ std::string MergePaths(const std::string& filePathPrefix, const std::string& fil return prefix; } -#ifdef _MSC_VER +#ifdef _WIN32 prefixPathSeperator = GetWindowsPathSeperator(prefix); suffixPathSeperator = suffix[0] == '/' || suffix[0] == '\\' ? suffix[0] : prefixPathSeperator; #endif diff --git a/vtkm/io/VTKDataSetReaderBase.cxx b/vtkm/io/VTKDataSetReaderBase.cxx index 3fcfc27ea..4dc305adf 100644 --- a/vtkm/io/VTKDataSetReaderBase.cxx +++ b/vtkm/io/VTKDataSetReaderBase.cxx @@ -297,9 +297,16 @@ void VTKDataSetReaderBase::ReadCells(vtkm::cont::ArrayHandle& connecti offsets.CastAndCallForTypes, vtkm::List>( [&](const auto& offsetsAH) { - vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleOffsetsToNumComponents( - vtkm::cont::make_ArrayHandleCast(offsetsAH, vtkm::Id{})), - numIndices); + // Convert on host. There will be several other passes of this array on the host anyway. + numIndices.Allocate(offsetsSize - 1); + auto offsetPortal = offsetsAH.ReadPortal(); + auto numIndicesPortal = numIndices.WritePortal(); + for (vtkm::Id cellIndex = 0; cellIndex < offsetsSize - 1; ++cellIndex) + { + numIndicesPortal.Set(cellIndex, + static_cast(offsetPortal.Get(cellIndex + 1) - + offsetPortal.Get(cellIndex))); + } }); this->DataFile->Stream >> tag >> dataType >> std::ws; diff --git a/vtkm/worklet/AverageByKey.h b/vtkm/worklet/AverageByKey.h index 64b186d2a..7f833fb6d 100644 --- a/vtkm/worklet/AverageByKey.h +++ b/vtkm/worklet/AverageByKey.h @@ -11,7 +11,7 @@ #define vtk_m_worklet_AverageByKey_h #include -#include +#include #include #include #include @@ -86,23 +86,13 @@ struct AverageByKey return outAverages; } - struct ExtractKey - { - template - VTKM_EXEC First operator()(const vtkm::Pair& pair) const - { - return pair.first; - } - }; - struct ExtractMean { - template - VTKM_EXEC ValueType operator()( - const vtkm::Pair>& pair) - const + template + VTKM_EXEC ValueType + operator()(const vtkm::worklet::DescriptiveStatistics::StatState& state) const { - return pair.second.Mean(); + return state.Mean(); } }; @@ -131,13 +121,15 @@ struct AverageByKey VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "AverageByKey::Run"); auto results = vtkm::worklet::DescriptiveStatistics::Run(keyArray, valueArray); - - // Copy/TransformCopy from results to outputKeyArray and outputValueArray - auto results_key = vtkm::cont::make_ArrayHandleTransform(results, ExtractKey{}); - auto results_mean = vtkm::cont::make_ArrayHandleTransform(results, ExtractMean{}); - - vtkm::cont::ArrayCopy(results_key, outputKeyArray); - vtkm::cont::ArrayCopy(results_mean, outputValueArray); + // Extract results to outputKeyArray and outputValueArray + outputKeyArray = results.GetFirstArray(); + // TODO: DescriptiveStatistics should write its output to a SOA instead of an AOS. + // An ArrayHandle of a weird struct by itself is not useful in any general algorithm. + // In fact, using DescriptiveStatistics at all seems like way overkill. It computes + // all sorts of statistics, and we then throw them all away except for mean. + auto resultsMean = + vtkm::cont::make_ArrayHandleTransform(results.GetSecondArray(), ExtractMean{}); + vtkm::cont::ArrayCopyDevice(resultsMean, outputValueArray); } }; } diff --git a/vtkm/worklet/CMakeLists.txt b/vtkm/worklet/CMakeLists.txt index 664dfc480..b540a5965 100644 --- a/vtkm/worklet/CMakeLists.txt +++ b/vtkm/worklet/CMakeLists.txt @@ -19,17 +19,11 @@ set(headers ContourTreeUniformAugmented.h CoordinateSystemTransform.h CosmoTools.h - CrossProduct.h DispatcherMapField.h DispatcherMapTopology.h DispatcherCellNeighborhood.h DispatcherPointNeighborhood.h DispatcherReduceByKey.h - DotProduct.h - ExtractGeometry.h - ExtractStructured.h - FieldEntropy.h - FieldHistogram.h FieldStatistics.h Gradient.h ImageDifference.h @@ -38,15 +32,12 @@ set(headers Keys.h LagrangianStructures.h Magnitude.h - Mask.h MaskIndices.h MaskNone.h MaskSelect.h MeshQuality.h MIR.h - NDimsEntropy.h NDimsHistMarginalization.h - NDimsHistogram.h Normalize.h OrientCellNormals.h OrientNormals.h @@ -69,7 +60,6 @@ set(headers StreamSurface.h SurfaceNormals.h Tetrahedralize.h - Threshold.h TriangleWinding.h Triangulate.h Tube.h @@ -117,7 +107,6 @@ set(sources_device add_subdirectory(internal) add_subdirectory(cellmetrics) add_subdirectory(colorconversion) -add_subdirectory(connectivities) add_subdirectory(contourtree) add_subdirectory(contourtree_augmented) add_subdirectory(contourtree_distributed) diff --git a/vtkm/worklet/CrossProduct.h b/vtkm/worklet/CrossProduct.h deleted file mode 100644 index 583e9b6ed..000000000 --- a/vtkm/worklet/CrossProduct.h +++ /dev/null @@ -1,38 +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_worklet_CrossProduct_h -#define vtk_m_worklet_CrossProduct_h - -#include - -#include - -namespace vtkm -{ -namespace worklet -{ - -class CrossProduct : public vtkm::worklet::WorkletMapField -{ -public: - using ControlSignature = void(FieldIn, FieldIn, FieldOut); - - template - VTKM_EXEC void operator()(const vtkm::Vec& vec1, - const vtkm::Vec& vec2, - vtkm::Vec& outVec) const - { - outVec = vtkm::Cross(vec1, vec2); - } -}; -} -} // namespace vtkm::worklet - -#endif // vtk_m_worklet_CrossProduct_h diff --git a/vtkm/worklet/DotProduct.h b/vtkm/worklet/DotProduct.h deleted file mode 100644 index 9c65bbce8..000000000 --- a/vtkm/worklet/DotProduct.h +++ /dev/null @@ -1,45 +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_worklet_DotProduct_h -#define vtk_m_worklet_DotProduct_h - -#include - -#include -#include - -namespace vtkm -{ -namespace worklet -{ - -class DotProduct : public vtkm::worklet::WorkletMapField -{ -public: - using ControlSignature = void(FieldIn, FieldIn, FieldOut); - - template - VTKM_EXEC void operator()(const vtkm::Vec& v1, - const vtkm::Vec& v2, - T& outValue) const - { - outValue = static_cast(vtkm::Dot(v1, v2)); - } - - template - VTKM_EXEC void operator()(T s1, T s2, T& outValue) const - { - outValue = static_cast(s1 * s2); - } -}; -} -} // namespace vtkm::worklet - -#endif // vtk_m_worklet_Normalize_h diff --git a/vtkm/worklet/contourtree_augmented/ArrayTransforms.h b/vtkm/worklet/contourtree_augmented/ArrayTransforms.h index f8e740f0e..a7fab02fc 100644 --- a/vtkm/worklet/contourtree_augmented/ArrayTransforms.h +++ b/vtkm/worklet/contourtree_augmented/ArrayTransforms.h @@ -56,7 +56,7 @@ // global libraries #include -#include +#include #include #include #include @@ -106,7 +106,7 @@ inline void PermuteArray(const ArrayType& input, IdArrayType& permute, ArrayType // fancy vtkm array so that we do not actually copy any data here permute_type permutedInput(maskedPermuteIndex, input); // Finally, copy the permuted values to the output array - vtkm::cont::ArrayCopy(permutedInput, output); + vtkm::cont::ArrayCopyDevice(permutedInput, output); } // permuteValues() diff --git a/vtkm/worklet/particleadvection/ParticleAdvectionWorklets.h b/vtkm/worklet/particleadvection/ParticleAdvectionWorklets.h index e552a3fa4..8fda04b7f 100644 --- a/vtkm/worklet/particleadvection/ParticleAdvectionWorklets.h +++ b/vtkm/worklet/particleadvection/ParticleAdvectionWorklets.h @@ -225,7 +225,7 @@ public: vtkm::cont::ArrayHandle cellIndex; vtkm::Id connectivityLen = vtkm::cont::Algorithm::ScanExclusive(numPoints, cellIndex); - vtkm::cont::ArrayHandleCounting connCount(0, 1, connectivityLen); + vtkm::cont::ArrayHandleIndex connCount(connectivityLen); vtkm::cont::ArrayHandle connectivity; vtkm::cont::ArrayCopy(connCount, connectivity); diff --git a/vtkm/worklet/testing/CMakeLists.txt b/vtkm/worklet/testing/CMakeLists.txt index 03660c62a..932b930a7 100644 --- a/vtkm/worklet/testing/CMakeLists.txt +++ b/vtkm/worklet/testing/CMakeLists.txt @@ -19,38 +19,23 @@ set(unit_tests UnitTestCellAverage.cxx UnitTestCellDeepCopy.cxx UnitTestCellGradient.cxx - UnitTestCellSetConnectivity.cxx - UnitTestCellSetDualGraph.cxx UnitTestCellMeasure.cxx - UnitTestClipping.cxx UnitTestContourTreeUniform.cxx UnitTestContourTreeUniformAugmented.cxx UnitTestContourTreeUniformDistributed.cxx UnitTestCoordinateSystemTransform.cxx UnitTestCosmoTools.cxx - UnitTestCrossProduct.cxx UnitTestDescriptiveStatistics.cxx - UnitTestDotProduct.cxx - UnitTestExtractGeometry.cxx - UnitTestExtractStructured.cxx - UnitTestFieldHistogram.cxx UnitTestFieldStatistics.cxx - UnitTestGraphConnectivity.cxx - UnitTestInnerJoin.cxx - UnitTestImageConnectivity.cxx UnitTestKeys.cxx UnitTestMagnitude.cxx - UnitTestMask.cxx UnitTestMaskIndices.cxx UnitTestMaskSelect.cxx UnitTestNormalize.cxx - UnitTestNDimsEntropy.cxx - UnitTestNDimsHistogram.cxx UnitTestNDimsHistMarginalization.cxx UnitTestOrientNormals.cxx UnitTestParticleAdvection.cxx UnitTestPointElevation.cxx - UnitTestPointerJumping.cxx UnitTestPointGradient.cxx UnitTestPointTransform.cxx UnitTestProbe.cxx @@ -66,7 +51,6 @@ set(unit_tests UnitTestSurfaceNormals.cxx UnitTestTemporalAdvection.cxx UnitTestTetrahedralize.cxx - UnitTestThreshold.cxx UnitTestTriangleWinding.cxx UnitTestTriangulate.cxx UnitTestTube.cxx diff --git a/vtkm/worklet/testing/UnitTestAverageByKey.cxx b/vtkm/worklet/testing/UnitTestAverageByKey.cxx index 14a2e5ae0..2fa4dae5b 100644 --- a/vtkm/worklet/testing/UnitTestAverageByKey.cxx +++ b/vtkm/worklet/testing/UnitTestAverageByKey.cxx @@ -70,7 +70,8 @@ void TryKeyType(KeyType) VTKM_TEST_ASSERT(keys.GetInputRange() == NUM_UNIQUE, "Keys has bad input range."); // Create values array - vtkm::cont::ArrayHandleCounting valuesArray(0.0f, 1.0f, ARRAY_SIZE); + vtkm::cont::ArrayHandle valuesArray; + vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), valuesArray); std::cout << " Try average with Keys object" << std::endl; CheckAverageByKey(keys.GetUniqueKeys(), vtkm::worklet::AverageByKey::Run(keys, valuesArray)); diff --git a/vtkm/worklet/testing/UnitTestCellSetConnectivity.cxx b/vtkm/worklet/testing/UnitTestCellSetConnectivity.cxx deleted file mode 100644 index c0eb6514f..000000000 --- a/vtkm/worklet/testing/UnitTestCellSetConnectivity.cxx +++ /dev/null @@ -1,88 +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 - -class TestCellSetConnectivity -{ -public: - void TestTangleIsosurface() const - { - vtkm::Id3 dims(4, 4, 4); - vtkm::source::Tangle tangle(dims); - vtkm::cont::DataSet dataSet = tangle.Execute(); - - vtkm::filter::contour::Contour filter; - filter.SetGenerateNormals(true); - filter.SetMergeDuplicatePoints(true); - filter.SetIsoValue(0, 0.1); - filter.SetActiveField("tangle"); - vtkm::cont::DataSet outputData = filter.Execute(dataSet); - - auto cellSet = outputData.GetCellSet().AsCellSet>(); - vtkm::cont::ArrayHandle componentArray; - vtkm::worklet::connectivity::CellSetConnectivity().Run(cellSet, componentArray); - - using Algorithm = vtkm::cont::Algorithm; - Algorithm::Sort(componentArray); - Algorithm::Unique(componentArray); - VTKM_TEST_ASSERT(componentArray.GetNumberOfValues() == 8, - "Wrong number of connected components"); - } - - void TestExplicitDataSet() const - { - vtkm::cont::DataSet dataSet = vtkm::cont::testing::MakeTestDataSet().Make3DExplicitDataSet5(); - - auto cellSet = dataSet.GetCellSet().AsCellSet>(); - vtkm::cont::ArrayHandle componentArray; - vtkm::worklet::connectivity::CellSetConnectivity().Run(cellSet, componentArray); - - using Algorithm = vtkm::cont::Algorithm; - Algorithm::Sort(componentArray); - Algorithm::Unique(componentArray); - VTKM_TEST_ASSERT(componentArray.GetNumberOfValues() == 1, - "Wrong number of connected components"); - } - - void TestUniformDataSet() const - { - vtkm::cont::DataSet dataSet = vtkm::cont::testing::MakeTestDataSet().Make3DUniformDataSet1(); - - auto cellSet = dataSet.GetCellSet(); - vtkm::cont::ArrayHandle componentArray; - vtkm::worklet::connectivity::CellSetConnectivity().Run(cellSet, componentArray); - - using Algorithm = vtkm::cont::Algorithm; - Algorithm::Sort(componentArray); - Algorithm::Unique(componentArray); - VTKM_TEST_ASSERT(componentArray.GetNumberOfValues() == 1, - "Wrong number of connected components"); - } - - void operator()() const - { - this->TestTangleIsosurface(); - this->TestExplicitDataSet(); - this->TestUniformDataSet(); - } -}; - -int UnitTestCellSetConnectivity(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestCellSetConnectivity(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestCellSetDualGraph.cxx b/vtkm/worklet/testing/UnitTestCellSetDualGraph.cxx index 6aba54d0c..e69de29bb 100644 --- a/vtkm/worklet/testing/UnitTestCellSetDualGraph.cxx +++ b/vtkm/worklet/testing/UnitTestCellSetDualGraph.cxx @@ -1,112 +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 - -class TestCellSetDualGraph -{ -private: - using GroupedConnectivityArrayType = - vtkm::cont::ArrayHandleGroupVecVariable, - vtkm::cont::ArrayHandle>; - - static GroupedConnectivityArrayType MakeGroupedConnectivity( - vtkm::cont::ArrayHandle connectivity, - vtkm::cont::ArrayHandle counts) - { - return GroupedConnectivityArrayType(connectivity, - vtkm::cont::ConvertNumComponentsToOffsets(counts)); - } - - static bool TestConnectivity(GroupedConnectivityArrayType computedConnectivityArray, - GroupedConnectivityArrayType expectedConnectivityArray) - { - auto computedConnections = computedConnectivityArray.ReadPortal(); - auto expectedConnections = expectedConnectivityArray.ReadPortal(); - - vtkm::Id numItems = computedConnections.GetNumberOfValues(); - if (numItems != expectedConnections.GetNumberOfValues()) - { - return false; - } - - for (vtkm::Id itemIndex = 0; itemIndex < numItems; ++itemIndex) - { - auto computed = computedConnections.Get(itemIndex); - auto expected = expectedConnections.Get(itemIndex); - vtkm::IdComponent numConnections = computed.GetNumberOfComponents(); - if (numConnections != expected.GetNumberOfComponents()) - { - return false; - } - - // computed and expected are Vec-like objects that should represent the same thing. - // However, although both should have the same indices, they may be in different - // orders. - std::set computedSet; - std::set expectedSet; - for (vtkm::IdComponent componentIndex = 0; componentIndex < numConnections; ++componentIndex) - { - computedSet.insert(computed[componentIndex]); - expectedSet.insert(expected[componentIndex]); - } - if (computedSet != expectedSet) - { - return false; - } - } - - return true; - } - -public: - void TestTriangleMesh() const - { - auto connectivity = vtkm::cont::make_ArrayHandle( - { 0, 2, 4, 1, 3, 5, 2, 6, 4, 5, 3, 7, 2, 9, 6, 4, 6, 8 }); - - vtkm::cont::CellSetSingleType<> cellSet; - cellSet.Fill(10, vtkm::CELL_SHAPE_TRIANGLE, 3, connectivity); - - vtkm::cont::ArrayHandle numIndicesArray; - vtkm::cont::ArrayHandle indexOffsetArray; - vtkm::cont::ArrayHandle connectivityArray; - - vtkm::worklet::connectivity::CellSetDualGraph().Run( - cellSet, numIndicesArray, indexOffsetArray, connectivityArray); - - vtkm::cont::ArrayHandle expectedNumIndices = - vtkm::cont::make_ArrayHandle({ 1, 1, 3, 1, 1, 1 }); - VTKM_TEST_ASSERT( - test_equal_portals(numIndicesArray.ReadPortal(), expectedNumIndices.ReadPortal())); - - vtkm::cont::ArrayHandle expectedIndexOffset = - vtkm::cont::make_ArrayHandle({ 0, 1, 2, 5, 6, 7 }); - VTKM_TEST_ASSERT( - test_equal_portals(indexOffsetArray.ReadPortal(), expectedIndexOffset.ReadPortal())); - - vtkm::cont::ArrayHandle expectedConnectivity = - vtkm::cont::make_ArrayHandle({ 2, 3, 0, 4, 5, 1, 2, 2 }); - VTKM_TEST_ASSERT( - TestConnectivity(MakeGroupedConnectivity(connectivityArray, numIndicesArray), - MakeGroupedConnectivity(expectedConnectivity, numIndicesArray))); - } - - void operator()() const { this->TestTriangleMesh(); } -}; - -int UnitTestCellSetDualGraph(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestCellSetDualGraph(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestClipping.cxx b/vtkm/worklet/testing/UnitTestClipping.cxx deleted file mode 100644 index ffe2e4112..000000000 --- a/vtkm/worklet/testing/UnitTestClipping.cxx +++ /dev/null @@ -1,351 +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 -#include -#include -#include -#include - -#include - -#include - -using Coord3D = vtkm::Vec3f; - -const vtkm::Float32 clipValue = 0.5; - -template -bool TestArrayHandle(const vtkm::cont::ArrayHandle& ah, - const T* expected, - vtkm::Id size) -{ - if (size != ah.GetNumberOfValues()) - { - return false; - } - - for (vtkm::Id i = 0; i < size; ++i) - { - if (ah.ReadPortal().Get(i) != expected[i]) - { - return false; - } - } - - return true; -} - -vtkm::cont::DataSet MakeTestDatasetExplicit() -{ - std::vector coords; - coords.push_back(Coord3D(0.0f, 0.0f, 0.0f)); - coords.push_back(Coord3D(1.0f, 0.0f, 0.0f)); - coords.push_back(Coord3D(1.0f, 1.0f, 0.0f)); - coords.push_back(Coord3D(0.0f, 1.0f, 0.0f)); - - std::vector connectivity; - connectivity.push_back(0); - connectivity.push_back(1); - connectivity.push_back(3); - connectivity.push_back(3); - connectivity.push_back(1); - connectivity.push_back(2); - - vtkm::cont::DataSet ds; - vtkm::cont::DataSetBuilderExplicit builder; - ds = builder.Create(coords, vtkm::CellShapeTagTriangle(), 3, connectivity, "coords"); - - - std::vector values; - values.push_back(1.0); - values.push_back(2.0); - values.push_back(1.0); - values.push_back(0.0); - ds.AddPointField("scalars", values); - - values.clear(); - values.push_back(100.f); - values.push_back(-100.f); - ds.AddCellField("cellvar", values); - - return ds; -} - -vtkm::cont::DataSet MakeTestDatasetStructured() -{ - static constexpr vtkm::Id xdim = 3, ydim = 3; - static const vtkm::Id2 dim(xdim, ydim); - static constexpr vtkm::Id numVerts = xdim * ydim; - - vtkm::Float32 scalars[numVerts]; - for (vtkm::Id i = 0; i < numVerts; ++i) - { - scalars[i] = 1.0f; - } - scalars[4] = 0.0f; - - vtkm::cont::DataSet ds; - vtkm::cont::DataSetBuilderUniform builder; - ds = builder.Create(dim); - - ds.AddPointField("scalars", scalars, numVerts); - - std::vector cellvar = { -100.f, 100.f, 30.f, -30.f }; - ds.AddCellField("cellvar", cellvar); - - return ds; -} - -void TestClippingExplicit() -{ - vtkm::cont::DataSet ds = MakeTestDatasetExplicit(); - vtkm::worklet::Clip clip; - bool invertClip = false; - vtkm::cont::CellSetExplicit<> outputCellSet = - clip.Run(ds.GetCellSet(), - ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListFieldScalar{}, - VTKM_DEFAULT_STORAGE_LIST{}), - clipValue, - invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer(); - vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - vtkm::Id connectivitySize = 8; - vtkm::Id fieldSize = 7; - vtkm::Id expectedConnectivity[] = { 0, 1, 5, 4, 1, 2, 6, 5 }; - Coord3D expectedCoords[] = { - Coord3D(0.00f, 0.00f, 0.0f), Coord3D(1.00f, 0.00f, 0.0f), Coord3D(1.00f, 1.00f, 0.0f), - Coord3D(0.00f, 1.00f, 0.0f), Coord3D(0.00f, 0.50f, 0.0f), Coord3D(0.25f, 0.75f, 0.0f), - Coord3D(0.50f, 1.00f, 0.0f), - }; - vtkm::Float32 expectedScalars[] = { 1, 2, 1, 0, 0.5, 0.5, 0.5 }; - std::vector expectedCellvar = { 100.f, -100.f }; - - VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize, - "Wrong number of points in cell set."); - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClippingStructured() -{ - using CoordsValueType = vtkm::cont::ArrayHandleUniformPointCoordinates::ValueType; - using CoordsOutType = vtkm::cont::ArrayHandle; - - vtkm::cont::DataSet ds = MakeTestDatasetStructured(); - - bool invertClip = false; - vtkm::worklet::Clip clip; - vtkm::cont::CellSetExplicit<> outputCellSet = - clip.Run(ds.GetCellSet(), - ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListFieldScalar{}, - VTKM_DEFAULT_STORAGE_LIST{}), - clipValue, - invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer(); - CoordsOutType coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - - vtkm::Id connectivitySize = 28; - vtkm::Id fieldSize = 13; - vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2, - 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 }; - - Coord3D expectedCoords[] = { - Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), - Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), - Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), - Coord3D(1.0f, 0.5f, 0.0f), Coord3D(0.5f, 1.0f, 0.0f), Coord3D(1.5f, 1.0f, 0.0f), - Coord3D(1.0f, 1.5f, 0.0f), - }; - vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5 }; - std::vector expectedCellvar = { -100.f, -100.f, 100.f, 100.f, - 30.f, 30.f, -30.f, -30.f }; - - VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize, - "Wrong number of points in cell set."); - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClippingWithImplicitFunction() -{ - vtkm::Vec3f center(1, 1, 0); - vtkm::FloatDefault radius(0.5); - - vtkm::cont::DataSet ds = MakeTestDatasetStructured(); - - bool invertClip = false; - vtkm::worklet::Clip clip; - vtkm::cont::CellSetExplicit<> outputCellSet = clip.Run( - ds.GetCellSet(), vtkm::Sphere(center, radius), ds.GetCoordinateSystem("coords"), invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer(); - vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - vtkm::Id connectivitySize = 28; - vtkm::Id fieldSize = 13; - - vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2, - 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 }; - - Coord3D expectedCoords[] = { - Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), - Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), - Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), - Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f), - Coord3D(1.0f, 1.25f, 0.0f), - }; - vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 }; - std::vector expectedCellvar = { -100.f, -100.f, 100.f, 100.f, - 30.f, 30.f, -30.f, -30.f }; - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClippingWithImplicitFunctionInverted() -{ - vtkm::Vec3f center(1, 1, 0); - vtkm::FloatDefault radius(0.5); - - vtkm::cont::DataSet ds = MakeTestDatasetStructured(); - - bool invertClip = true; - vtkm::worklet::Clip clip; - vtkm::cont::CellSetExplicit<> outputCellSet = clip.Run( - ds.GetCellSet(), vtkm::Sphere(center, radius), ds.GetCoordinateSystem("coords"), invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetDataAsMultiplexer(); - vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().AsArrayHandle(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().AsArrayHandle(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - vtkm::Id connectivitySize = 12; - vtkm::Id fieldSize = 13; - vtkm::Id expectedConnectivity[] = { 10, 9, 4, 9, 11, 4, 12, 10, 4, 11, 12, 4 }; - Coord3D expectedCoords[] = { - Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), - Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), - Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), - Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f), - Coord3D(1.0f, 1.25f, 0.0f), - }; - vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 }; - std::vector expectedCellvar = { -100.f, 100.f, 30.f, -30.f }; - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClipping() -{ - std::cout << "Testing explicit dataset:" << std::endl; - TestClippingExplicit(); - std::cout << "Testing structured dataset:" << std::endl; - TestClippingStructured(); - std::cout << "Testing clipping with implicit function (sphere):" << std::endl; - TestClippingWithImplicitFunction(); - TestClippingWithImplicitFunctionInverted(); -} - -int UnitTestClipping(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestClipping, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestClippingWithFunction.cxx b/vtkm/worklet/testing/UnitTestClippingWithFunction.cxx deleted file mode 100644 index c570e076a..000000000 --- a/vtkm/worklet/testing/UnitTestClippingWithFunction.cxx +++ /dev/null @@ -1,350 +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 -#include -#include -#include -#include -#include - - -#include - -using Coord3D = vtkm::Vec; - -const vtkm::Float32 clipValue = 0.5; - -template -bool TestArrayHandle(const vtkm::cont::ArrayHandle& ah, - const T* expected, - vtkm::Id size) -{ - if (size != ah.GetNumberOfValues()) - { - return false; - } - - for (vtkm::Id i = 0; i < size; ++i) - { - if (ah.ReadPortal().Get(i) != expected[i]) - { - return false; - } - } - - return true; -} - -vtkm::cont::DataSet MakeTestDatasetExplicit() -{ - std::vector coords; - coords.push_back(Coord3D(0.0f, 0.0f, 0.0f)); - coords.push_back(Coord3D(1.0f, 0.0f, 0.0f)); - coords.push_back(Coord3D(1.0f, 1.0f, 0.0f)); - coords.push_back(Coord3D(0.0f, 1.0f, 0.0f)); - - std::vector connectivity; - connectivity.push_back(0); - connectivity.push_back(1); - connectivity.push_back(3); - connectivity.push_back(3); - connectivity.push_back(1); - connectivity.push_back(2); - - vtkm::cont::DataSet ds; - vtkm::cont::DataSetBuilderExplicit builder; - ds = builder.Create(coords, vtkm::CellShapeTagTriangle(), 3, connectivity, "coords"); - - std::vector values; - values.push_back(1.0); - values.push_back(2.0); - values.push_back(1.0); - values.push_back(0.0); - ds.AddPointField("scalars", values); - - values.clear(); - values.push_back(100.f); - values.push_back(-100.f); - ds.AddCellField("cellvar", values); - - return ds; -} - -vtkm::cont::DataSet MakeTestDatasetStructured() -{ - static constexpr vtkm::Id xdim = 3, ydim = 3; - static const vtkm::Id2 dim(xdim, ydim); - static constexpr vtkm::Id numVerts = xdim * ydim; - - vtkm::Float32 scalars[numVerts]; - for (vtkm::Id i = 0; i < numVerts; ++i) - { - scalars[i] = 1.0f; - } - scalars[4] = 0.0f; - - vtkm::cont::DataSet ds; - vtkm::cont::DataSetBuilderUniform builder; - ds = builder.Create(dim); - - ds.AddPointField("scalars", scalars, numVerts); - - std::vector cellvar = { -100.f, 100.f, 30.f, -30.f }; - ds.AddCellField("cellvar", cellvar); - - return ds; -} - -void TestClippingExplicit() -{ - vtkm::cont::DataSet ds = MakeTestDatasetExplicit(); - vtkm::worklet::Clip clip; - bool invertClip = false; - vtkm::cont::CellSetExplicit<> outputCellSet = - clip.Run(ds.GetCellSet(), - ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListFieldScalar()), - clipValue, - invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); - vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().CopyTo(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().CopyTo(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - vtkm::Id connectivitySize = 8; - vtkm::Id fieldSize = 7; - vtkm::Id expectedConnectivity[] = { 0, 1, 5, 4, 1, 2, 6, 5 }; - const Coord3D expectedCoords[] = { - Coord3D(0.00f, 0.00f, 0.0f), Coord3D(1.00f, 0.00f, 0.0f), Coord3D(1.00f, 1.00f, 0.0f), - Coord3D(0.00f, 1.00f, 0.0f), Coord3D(0.00f, 0.50f, 0.0f), Coord3D(0.25f, 0.75f, 0.0f), - Coord3D(0.50f, 1.00f, 0.0f), - }; - const vtkm::Float32 expectedScalars[] = { 1, 2, 1, 0, 0.5, 0.5, 0.5 }; - std::vector expectedCellvar = { 100.f, -100.f }; - - VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize, - "Wrong number of points in cell set."); - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClippingStructured() -{ - using CoordsValueType = vtkm::cont::ArrayHandleUniformPointCoordinates::ValueType; - using CoordsOutType = vtkm::cont::ArrayHandle; - - vtkm::cont::DataSet ds = MakeTestDatasetStructured(); - - bool invertClip = false; - vtkm::worklet::Clip clip; - vtkm::cont::CellSetExplicit<> outputCellSet = - clip.Run(ds.GetCellSet(), - ds.GetField("scalars").GetData().ResetTypes(vtkm::TypeListFieldScalar()), - clipValue, - invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); - CoordsOutType coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().CopyTo(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().CopyTo(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - - vtkm::Id connectivitySize = 28; - vtkm::Id fieldSize = 13; - const vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2, - 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 }; - - const Coord3D expectedCoords[] = { - Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), - Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), - Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), - Coord3D(1.0f, 0.5f, 0.0f), Coord3D(0.5f, 1.0f, 0.0f), Coord3D(1.5f, 1.0f, 0.0f), - Coord3D(1.0f, 1.5f, 0.0f), - }; - const vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5 }; - std::vector expectedCellvar = { -100.f, -100.f, 100.f, 100.f, - 30.f, 30.f, -30.f, -30.f }; - - VTKM_TEST_ASSERT(outputCellSet.GetNumberOfPoints() == fieldSize, - "Wrong number of points in cell set."); - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClippingWithImplicitFunction() -{ - vtkm::Vec center(1, 1, 0); - vtkm::FloatDefault radius(0.5); - - vtkm::cont::DataSet ds = MakeTestDatasetStructured(); - - bool invertClip = false; - vtkm::worklet::Clip clip; - vtkm::cont::CellSetExplicit<> outputCellSet = - clip.Run(ds.GetCellSet(), - vtkm::cont::make_ImplicitFunctionHandle(center, radius), - ds.GetCoordinateSystem("coords"), - invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); - vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().CopyTo(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().CopyTo(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - vtkm::Id connectivitySize = 28; - vtkm::Id fieldSize = 13; - - const vtkm::Id expectedConnectivity[] = { 9, 10, 3, 1, 1, 3, 0, 11, 9, 1, 5, 5, 1, 2, - 10, 12, 7, 3, 3, 7, 6, 12, 11, 5, 7, 7, 5, 8 }; - - const Coord3D expectedCoords[] = { - Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), - Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), - Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), - Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f), - Coord3D(1.0f, 1.25f, 0.0f), - }; - const vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 }; - std::vector expectedCellvar = { -100.f, -100.f, 100.f, 100.f, - 30.f, 30.f, -30.f, -30.f }; - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClippingWithImplicitFunctionInverted() -{ - vtkm::Vec center(1, 1, 0); - vtkm::FloatDefault radius(0.5); - - vtkm::cont::DataSet ds = MakeTestDatasetStructured(); - - bool invertClip = true; - vtkm::worklet::Clip clip; - vtkm::cont::CellSetExplicit<> outputCellSet = - clip.Run(ds.GetCellSet(), - vtkm::cont::make_ImplicitFunctionHandle(center, radius), - ds.GetCoordinateSystem("coords"), - invertClip); - - auto coordsIn = ds.GetCoordinateSystem("coords").GetData(); - vtkm::cont::ArrayHandle coords = clip.ProcessPointField(coordsIn); - - vtkm::cont::ArrayHandle scalarsIn; - ds.GetField("scalars").GetData().CopyTo(scalarsIn); - vtkm::cont::ArrayHandle scalars = clip.ProcessPointField(scalarsIn); - - vtkm::cont::ArrayHandle cellvarIn; - ds.GetField("cellvar").GetData().CopyTo(cellvarIn); - vtkm::cont::ArrayHandle cellvar = clip.ProcessCellField(cellvarIn); - - vtkm::Id connectivitySize = 12; - vtkm::Id fieldSize = 13; - vtkm::Id expectedConnectivity[] = { 10, 9, 4, 9, 11, 4, 12, 10, 4, 11, 12, 4 }; - const Coord3D expectedCoords[] = { - Coord3D(0.0f, 0.0f, 0.0f), Coord3D(1.0f, 0.0f, 0.0f), Coord3D(2.0f, 0.0f, 0.0f), - Coord3D(0.0f, 1.0f, 0.0f), Coord3D(1.0f, 1.0f, 0.0f), Coord3D(2.0f, 1.0f, 0.0f), - Coord3D(0.0f, 2.0f, 0.0f), Coord3D(1.0f, 2.0f, 0.0f), Coord3D(2.0f, 2.0f, 0.0f), - Coord3D(1.0f, 0.75f, 0.0f), Coord3D(0.75f, 1.0f, 0.0f), Coord3D(1.25f, 1.0f, 0.0f), - Coord3D(1.0f, 1.25f, 0.0f), - }; - vtkm::Float32 expectedScalars[] = { 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.25, 0.25, 0.25, 0.25 }; - std::vector expectedCellvar = { -100.f, 100.f, 30.f, -30.f }; - - VTKM_TEST_ASSERT( - TestArrayHandle(outputCellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(), - vtkm::TopologyElementTagPoint()), - expectedConnectivity, - connectivitySize), - "Got incorrect conectivity"); - - VTKM_TEST_ASSERT(TestArrayHandle(coords, expectedCoords, fieldSize), "Got incorrect coordinates"); - - VTKM_TEST_ASSERT(TestArrayHandle(scalars, expectedScalars, fieldSize), "Got incorrect scalars"); - - VTKM_TEST_ASSERT( - TestArrayHandle(cellvar, expectedCellvar.data(), static_cast(expectedCellvar.size())), - "Got incorrect cellvar"); -} - -void TestClippingWithFunction() -{ - std::cout << "Testing clipping with implicit function (sphere):" << std::endl; - TestClippingWithImplicitFunction(); - TestClippingWithImplicitFunctionInverted(); -} - -int UnitTestClippingWithFunction(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestClippingWithFunction, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestCrossProduct.cxx b/vtkm/worklet/testing/UnitTestCrossProduct.cxx deleted file mode 100644 index 835031726..000000000 --- a/vtkm/worklet/testing/UnitTestCrossProduct.cxx +++ /dev/null @@ -1,118 +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 -{ -std::mt19937 randGenerator; - -template -void createVectors(std::vector>& vecs1, std::vector>& vecs2) -{ - // First, test the standard directions. - // X x Y - vecs1.push_back(vtkm::make_Vec(1, 0, 0)); - vecs2.push_back(vtkm::make_Vec(0, 1, 0)); - - // Y x Z - vecs1.push_back(vtkm::make_Vec(0, 1, 0)); - vecs2.push_back(vtkm::make_Vec(0, 0, 1)); - - // Z x X - vecs1.push_back(vtkm::make_Vec(0, 0, 1)); - vecs2.push_back(vtkm::make_Vec(1, 0, 0)); - - // Y x X - vecs1.push_back(vtkm::make_Vec(0, 1, 0)); - vecs2.push_back(vtkm::make_Vec(1, 0, 0)); - - // Z x Y - vecs1.push_back(vtkm::make_Vec(0, 0, 1)); - vecs2.push_back(vtkm::make_Vec(0, 1, 0)); - - // X x Z - vecs1.push_back(vtkm::make_Vec(1, 0, 0)); - vecs2.push_back(vtkm::make_Vec(0, 0, 1)); - - //Test some other vector combinations - std::uniform_real_distribution randomDist(-10.0, 10.0); - - for (int i = 0; i < 100; i++) - { - vecs1.push_back(vtkm::make_Vec( - randomDist(randGenerator), randomDist(randGenerator), randomDist(randGenerator))); - vecs2.push_back(vtkm::make_Vec( - randomDist(randGenerator), randomDist(randGenerator), randomDist(randGenerator))); - } -} - -template -void TestCrossProduct() -{ - std::vector> inputVecs1, inputVecs2; - createVectors(inputVecs1, inputVecs2); - - vtkm::cont::ArrayHandle> inputArray1, inputArray2; - vtkm::cont::ArrayHandle> outputArray; - inputArray1 = vtkm::cont::make_ArrayHandle(inputVecs1, vtkm::CopyFlag::Off); - inputArray2 = vtkm::cont::make_ArrayHandle(inputVecs2, vtkm::CopyFlag::Off); - - vtkm::worklet::CrossProduct crossProductWorklet; - vtkm::worklet::DispatcherMapField dispatcherCrossProduct( - crossProductWorklet); - dispatcherCrossProduct.Invoke(inputArray1, inputArray2, outputArray); - - VTKM_TEST_ASSERT(outputArray.GetNumberOfValues() == inputArray1.GetNumberOfValues(), - "Wrong number of results for CrossProduct worklet"); - - //Test the canonical cases. - VTKM_TEST_ASSERT(test_equal(outputArray.ReadPortal().Get(0), vtkm::make_Vec(0, 0, 1)) && - test_equal(outputArray.ReadPortal().Get(1), vtkm::make_Vec(1, 0, 0)) && - test_equal(outputArray.ReadPortal().Get(2), vtkm::make_Vec(0, 1, 0)) && - test_equal(outputArray.ReadPortal().Get(3), vtkm::make_Vec(0, 0, -1)) && - test_equal(outputArray.ReadPortal().Get(4), vtkm::make_Vec(-1, 0, 0)) && - test_equal(outputArray.ReadPortal().Get(5), vtkm::make_Vec(0, -1, 0)), - "Wrong result for CrossProduct worklet"); - - for (vtkm::Id i = 0; i < inputArray1.GetNumberOfValues(); i++) - { - vtkm::Vec v1 = inputArray1.ReadPortal().Get(i); - vtkm::Vec v2 = inputArray2.ReadPortal().Get(i); - vtkm::Vec res = outputArray.ReadPortal().Get(i); - - //Make sure result is orthogonal each input vector. Need to normalize to compare with zero. - vtkm::Vec v1N(vtkm::Normal(v1)), v2N(vtkm::Normal(v1)), resN(vtkm::Normal(res)); - VTKM_TEST_ASSERT(test_equal(vtkm::Dot(resN, v1N), T(0.0)), "Wrong result for cross product"); - VTKM_TEST_ASSERT(test_equal(vtkm::Dot(resN, v2N), T(0.0)), "Wrong result for cross product"); - - T sinAngle = vtkm::Magnitude(res) * vtkm::RMagnitude(v1) * vtkm::RMagnitude(v2); - T cosAngle = vtkm::Dot(v1, v2) * vtkm::RMagnitude(v1) * vtkm::RMagnitude(v2); - VTKM_TEST_ASSERT(test_equal(sinAngle * sinAngle + cosAngle * cosAngle, T(1.0)), - "Bad cross product length."); - } -} - -void TestCrossProductWorklets() -{ - std::cout << "Testing CrossProduct Worklet" << std::endl; - TestCrossProduct(); - TestCrossProduct(); -} -} - -int UnitTestCrossProduct(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestCrossProductWorklets, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestDotProduct.cxx b/vtkm/worklet/testing/UnitTestDotProduct.cxx deleted file mode 100644 index 5c2978ea3..000000000 --- a/vtkm/worklet/testing/UnitTestDotProduct.cxx +++ /dev/null @@ -1,105 +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 - -namespace -{ - -template -T normalizedVector(T v) -{ - T vN = vtkm::Normal(v); - return vN; -} - -template -void createVectors(std::vector>& vecs1, - std::vector>& vecs2, - std::vector& result) -{ - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(1), T(0), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(1), T(0), T(0)))); - result.push_back(1); - - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(1), T(0), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(-1), T(0), T(0)))); - result.push_back(-1); - - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(1), T(0), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(0), T(1), T(0)))); - result.push_back(0); - - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(1), T(0), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(0), T(-1), T(0)))); - result.push_back(0); - - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(1), T(0), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(1), T(1), T(0)))); - result.push_back(T(1.0 / vtkm::Sqrt(2.0))); - - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(1), T(1), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(1), T(0), T(0)))); - result.push_back(T(1.0 / vtkm::Sqrt(2.0))); - - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(-1), T(0), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(1), T(1), T(0)))); - result.push_back(-T(1.0 / vtkm::Sqrt(2.0))); - - vecs1.push_back(normalizedVector(vtkm::make_Vec(T(0), T(1), T(0)))); - vecs2.push_back(normalizedVector(vtkm::make_Vec(T(1), T(1), T(0)))); - result.push_back(T(1.0 / vtkm::Sqrt(2.0))); -} - -template -void TestDotProduct() -{ - std::vector> inputVecs1, inputVecs2; - std::vector answer; - createVectors(inputVecs1, inputVecs2, answer); - - vtkm::cont::ArrayHandle> inputArray1, inputArray2; - vtkm::cont::ArrayHandle outputArray; - inputArray1 = vtkm::cont::make_ArrayHandle(inputVecs1, vtkm::CopyFlag::Off); - inputArray2 = vtkm::cont::make_ArrayHandle(inputVecs2, vtkm::CopyFlag::Off); - - vtkm::worklet::DotProduct dotProductWorklet; - vtkm::worklet::DispatcherMapField dispatcherDotProduct( - dotProductWorklet); - dispatcherDotProduct.Invoke(inputArray1, inputArray2, outputArray); - - VTKM_TEST_ASSERT(outputArray.GetNumberOfValues() == inputArray1.GetNumberOfValues(), - "Wrong number of results for DotProduct worklet"); - - for (vtkm::Id i = 0; i < inputArray1.GetNumberOfValues(); i++) - { - vtkm::Vec v1 = inputArray1.ReadPortal().Get(i); - vtkm::Vec v2 = inputArray2.ReadPortal().Get(i); - T ans = answer[static_cast(i)]; - - VTKM_TEST_ASSERT(test_equal(ans, vtkm::Dot(v1, v2)), "Wrong result for dot product"); - } -} - -void TestDotProductWorklets() -{ - std::cout << "Testing DotProduct Worklet" << std::endl; - TestDotProduct(); - // TestDotProduct(); -} -} - -int UnitTestDotProduct(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestDotProductWorklets, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestExtractGeometry.cxx b/vtkm/worklet/testing/UnitTestExtractGeometry.cxx deleted file mode 100644 index 3a4106364..000000000 --- a/vtkm/worklet/testing/UnitTestExtractGeometry.cxx +++ /dev/null @@ -1,255 +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 - -using vtkm::cont::testing::MakeTestDataSet; - -class TestingExtractGeometry -{ -public: - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestExplicitById() const - { - std::cout << "Testing extract cell explicit by id:" << std::endl; - - using CellSetType = vtkm::cont::CellSetExplicit<>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Cells to extract - vtkm::cont::ArrayHandle cellIds = vtkm::cont::make_ArrayHandle({ 1, 2 }); - const vtkm::Id nCells = cellIds.GetNumberOfValues(); - - // Output data set with cell set containing extracted cells and all points - vtkm::worklet::ExtractGeometry extractGeometry; - OutCellSetType outCellSet = extractGeometry.Run(cellSet, cellIds); - - auto cellvar = - dataset.GetField("cellvar").GetData().AsArrayHandle>(); - auto cellFieldArray = extractGeometry.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), nCells), - "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == nCells && - cellFieldArray.ReadPortal().Get(0) == 110.f, - "Wrong cell field data"); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestExplicitByBox() const - { - std::cout << "Testing extract cells with implicit function (box) on explicit:" << std::endl; - - using CellSetType = vtkm::cont::CellSetExplicit<>; - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Implicit function - vtkm::Vec3f minPoint(0.5f, 0.0f, 0.0f); - vtkm::Vec3f maxPoint(2.0f, 2.0f, 2.0f); - - bool extractInside = true; - bool extractBoundaryCells = false; - bool extractOnlyBoundaryCells = false; - - // Output data set with cell set containing extracted cells and all points - vtkm::worklet::ExtractGeometry extractGeometry; - vtkm::cont::UnknownCellSet outCellSet = - extractGeometry.Run(cellSet, - dataset.GetCoordinateSystem("coordinates"), - vtkm::Box(minPoint, maxPoint), - extractInside, - extractBoundaryCells, - extractOnlyBoundaryCells); - - auto cellvar = - dataset.GetField("cellvar").GetData().AsArrayHandle>(); - auto cellFieldArray = extractGeometry.ProcessCellField(cellvar); - - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 2), "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 2 && - cellFieldArray.ReadPortal().Get(1) == 120.2f, - "Wrong cell field data"); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestUniformById2D() const - { - std::cout << "Testing extract cells structured by id:" << std::endl; - - using CellSetType = vtkm::cont::CellSetStructured<2>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet1(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Cells to extract - vtkm::cont::ArrayHandle cellIds = - vtkm::cont::make_ArrayHandle({ 0, 4, 5, 10, 15 }); - const vtkm::Id nCells = cellIds.GetNumberOfValues(); - - // Output data set permutation of with only extracted cells - vtkm::worklet::ExtractGeometry extractGeometry; - OutCellSetType outCellSet = extractGeometry.Run(cellSet, cellIds); - - auto cellvar = - dataset.GetField("cellvar").GetData().AsArrayHandle>(); - auto cellFieldArray = extractGeometry.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), nCells), - "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == nCells && - cellFieldArray.ReadPortal().Get(1) == 4.f, - "Wrong cell field data"); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestUniformById3D() const - { - std::cout << "Testing extract cells structured by id:" << std::endl; - - using CellSetType = vtkm::cont::CellSetStructured<3>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Cells to extract - vtkm::cont::ArrayHandle cellIds = - vtkm::cont::make_ArrayHandle({ 0, 4, 5, 10, 15 }); - const vtkm::Id nCells = cellIds.GetNumberOfValues(); - - // Output data set with cell set containing extracted cells and all points - vtkm::worklet::ExtractGeometry extractGeometry; - OutCellSetType outCellSet = extractGeometry.Run(cellSet, cellIds); - - auto cellvar = - dataset.GetField("cellvar").GetData().AsArrayHandle>(); - auto cellFieldArray = extractGeometry.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), nCells), - "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == nCells && - cellFieldArray.ReadPortal().Get(2) == 5.f, - "Wrong cell field data"); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestUniformByBox() const - { - std::cout << "Testing extract cells with implicit function (box):" << std::endl; - - using CellSetType = vtkm::cont::CellSetStructured<3>; - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Implicit function - vtkm::Vec3f minPoint(1.0f, 1.0f, 1.0f); - vtkm::Vec3f maxPoint(3.0f, 3.0f, 3.0f); - - bool extractInside = true; - bool extractBoundaryCells = false; - bool extractOnlyBoundaryCells = false; - - // Output data set with cell set containing extracted points - vtkm::worklet::ExtractGeometry extractGeometry; - vtkm::cont::UnknownCellSet outCellSet = - extractGeometry.Run(cellSet, - dataset.GetCoordinateSystem("coords"), - vtkm::Box(minPoint, maxPoint), - extractInside, - extractBoundaryCells, - extractOnlyBoundaryCells); - - auto cellvar = - dataset.GetField("cellvar").GetData().AsArrayHandle>(); - auto cellFieldArray = extractGeometry.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 8 && - cellFieldArray.ReadPortal().Get(0) == 21.f, - "Wrong cell field data"); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestUniformBySphere() const - { - std::cout << "Testing extract cells with implicit function (sphere):" << std::endl; - - using CellSetType = vtkm::cont::CellSetStructured<3>; - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Implicit function - vtkm::Vec3f center(2.f, 2.f, 2.f); - vtkm::FloatDefault radius(1.8f); - - bool extractInside = true; - bool extractBoundaryCells = false; - bool extractOnlyBoundaryCells = false; - - // Output data set with cell set containing extracted cells - vtkm::worklet::ExtractGeometry extractGeometry; - vtkm::cont::UnknownCellSet outCellSet = - extractGeometry.Run(cellSet, - dataset.GetCoordinateSystem("coords"), - vtkm::Sphere(center, radius), - extractInside, - extractBoundaryCells, - extractOnlyBoundaryCells); - - auto cellvar = - dataset.GetField("cellvar").GetData().AsArrayHandle>(); - auto cellFieldArray = extractGeometry.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 8 && - cellFieldArray.ReadPortal().Get(1) == 22.f, - "Wrong cell field data"); - } - - void operator()() const - { - this->TestUniformById2D(); - this->TestUniformById3D(); - this->TestUniformBySphere(); - this->TestUniformByBox(); - this->TestExplicitById(); - this->TestExplicitByBox(); - } -}; - -int UnitTestExtractGeometry(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestingExtractGeometry(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestExtractStructured.cxx b/vtkm/worklet/testing/UnitTestExtractStructured.cxx deleted file mode 100644 index de000e2a1..000000000 --- a/vtkm/worklet/testing/UnitTestExtractStructured.cxx +++ /dev/null @@ -1,339 +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 - -using vtkm::cont::testing::MakeTestDataSet; - -class TestingExtractStructured -{ -public: - void TestUniform2D() const - { - std::cout << "Testing extract structured uniform 2D" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<2>; - - // Create the input uniform cell set - vtkm::cont::DataSet dataSet = MakeTestDataSet().Make2DUniformDataSet1(); - CellSetType cellSet; - dataSet.GetCellSet().AsCellSet(cellSet); - - // RangeId3 and subsample - vtkm::RangeId3 range(1, 4, 1, 4, 0, 1); - vtkm::Id3 sample(1, 1, 1); - bool includeBoundary = false; - bool includeOffset = false; - - vtkm::worklet::ExtractStructured worklet; - auto outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 9), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 4), - "Wrong result for ExtractStructured worklet"); - } - - void TestUniform3D() const - { - std::cout << "Testing extract structured uniform 3D" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<3>; - - // Create the input uniform cell set - vtkm::cont::DataSet dataSet = MakeTestDataSet().Make3DUniformDataSet1(); - CellSetType cellSet; - dataSet.GetCellSet().AsCellSet(cellSet); - - vtkm::worklet::ExtractStructured worklet; - vtkm::worklet::ExtractStructured::UncertainCellSetStructured outCellSet; - - // RangeId3 within dataset - vtkm::RangeId3 range0(1, 4, 1, 4, 1, 4); - vtkm::Id3 sample(1, 1, 1); - bool includeBoundary = false; - bool includeOffset = false; - - outCellSet = worklet.Run(cellSet, range0, sample, includeBoundary, includeOffset); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 27), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), - "Wrong result for ExtractStructured worklet"); - - // RangeId3 surrounds dataset - vtkm::RangeId3 range1(-1, 8, -1, 8, -1, 8); - outCellSet = worklet.Run(cellSet, range1, sample, includeBoundary, includeOffset); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 125), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 64), - "Wrong result for ExtractStructured worklet"); - - // RangeId3 intersects dataset on near boundary - vtkm::RangeId3 range2(-1, 3, -1, 3, -1, 3); - outCellSet = worklet.Run(cellSet, range2, sample, includeBoundary, includeOffset); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 27), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), - "Wrong result for ExtractStructured worklet"); - - // RangeId3 intersects dataset on far boundary - vtkm::RangeId3 range3(1, 8, 1, 8, 1, 8); - outCellSet = worklet.Run(cellSet, range3, sample, includeBoundary, includeOffset); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 64), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 27), - "Wrong result for ExtractStructured worklet"); - - // RangeId3 intersects dataset without corner - vtkm::RangeId3 range4(2, 8, 1, 4, 1, 4); - outCellSet = worklet.Run(cellSet, range4, sample, includeBoundary, includeOffset); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 27), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), - "Wrong result for ExtractStructured worklet"); - - // RangeId3 intersects dataset with plane - vtkm::RangeId3 range5(2, 8, 1, 2, 1, 4); - outCellSet = worklet.Run(cellSet, range5, sample, includeBoundary, includeOffset); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 9), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 4), - "Wrong result for ExtractStructured worklet"); - } - - void TestUniform3D1() const - { - std::cout << "Testing extract structured uniform with sampling" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<3>; - - // Create the input uniform cell set - vtkm::cont::DataSet dataSet = MakeTestDataSet().Make3DUniformDataSet1(); - CellSetType cellSet; - dataSet.GetCellSet().AsCellSet(cellSet); - - vtkm::worklet::ExtractStructured worklet; - vtkm::worklet::ExtractStructured::UncertainCellSetStructured outCellSet; - - // RangeId3 within data set with sampling - vtkm::RangeId3 range0(0, 5, 0, 5, 1, 4); - vtkm::Id3 sample0(2, 2, 1); - bool includeBoundary0 = false; - bool includeOffset = false; - - outCellSet = worklet.Run(cellSet, range0, sample0, includeBoundary0, includeOffset); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 27), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), - "Wrong result for ExtractStructured worklet"); - - // RangeId3 and subsample - vtkm::RangeId3 range1(0, 5, 0, 5, 1, 4); - vtkm::Id3 sample1(3, 3, 2); - bool includeBoundary1 = false; - - outCellSet = worklet.Run(cellSet, range1, sample1, includeBoundary1, includeOffset); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 8), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 1), - "Wrong result for ExtractStructured worklet"); - - // RangeId3 and subsample - vtkm::RangeId3 range2(0, 5, 0, 5, 1, 4); - vtkm::Id3 sample2(3, 3, 2); - bool includeBoundary2 = true; - - outCellSet = worklet.Run(cellSet, range2, sample2, includeBoundary2, includeOffset); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 18), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 4), - "Wrong result for ExtractStructured worklet"); - } - - void TestRectilinear2D() const - { - std::cout << "Testing extract structured rectilinear" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<2>; - - // Create the input uniform cell set - vtkm::cont::DataSet dataSet = MakeTestDataSet().Make2DRectilinearDataSet0(); - CellSetType cellSet; - dataSet.GetCellSet().AsCellSet(cellSet); - - // RangeId3 and subsample - vtkm::RangeId3 range(0, 2, 0, 2, 0, 1); - vtkm::Id3 sample(1, 1, 1); - bool includeBoundary = false; - bool includeOffset = false; - - // Extract subset - vtkm::worklet::ExtractStructured worklet; - auto outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 4), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 1), - "Wrong result for ExtractStructured worklet"); - } - - void TestRectilinear3D() const - { - std::cout << "Testing extract structured rectilinear" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<3>; - - // Create the input uniform cell set - vtkm::cont::DataSet dataSet = MakeTestDataSet().Make3DRectilinearDataSet0(); - CellSetType cellSet; - dataSet.GetCellSet().AsCellSet(cellSet); - - // RangeId3 and subsample - vtkm::RangeId3 range(0, 2, 0, 2, 0, 2); - vtkm::Id3 sample(1, 1, 1); - bool includeBoundary = false; - bool includeOffset = false; - - // Extract subset - vtkm::worklet::ExtractStructured worklet; - auto outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfPoints(), 8), - "Wrong result for ExtractStructured worklet"); - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 1), - "Wrong result for ExtractStructured worklet"); - } - - void TestOffset3D1() const - { - std::cout << "Testing offset 3D-1" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<3>; - - CellSetType cellSet; - - // RangeID3 and subsample - vtkm::RangeId3 range(5, 15, 0, 10, 0, 10); - vtkm::Id3 sample(1, 1, 1); - vtkm::Id3 test_offset(10, 0, 0); - vtkm::Id3 no_offset(0, 0, 0); - vtkm::Id3 new_dims(5, 10, 10); - bool includeBoundary = false; - bool includeOffset = false; - cellSet.SetPointDimensions(vtkm::make_Vec(10, 10, 10)); - - vtkm::worklet::ExtractStructured worklet; - auto outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - - VTKM_TEST_ASSERT(test_equal(cellSet.GetGlobalPointIndexStart(), no_offset)); - vtkm::Id3 cellDims = - outCellSet.AsCellSet().GetSchedulingRange(vtkm::TopologyElementTagCell()); - - includeOffset = true; - cellSet.SetGlobalPointIndexStart(test_offset); - outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - cellDims = - outCellSet.AsCellSet().GetSchedulingRange(vtkm::TopologyElementTagCell()); - CellSetType cs = outCellSet.AsCellSet(); - cellDims = cs.GetPointDimensions(); - VTKM_TEST_ASSERT(test_equal(cellDims, new_dims)); - VTKM_TEST_ASSERT(test_equal(cellSet.GetGlobalPointIndexStart(), test_offset)); - } - - void TestOffset3D2() const - { - std::cout << "Testing Offset 3D-2" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<3>; - CellSetType cellSet; - vtkm::RangeId3 range(15, 20, 0, 10, 0, 10); - vtkm::Id3 sample(1, 1, 1); - vtkm::Id3 test_dims(5, 10, 10); - vtkm::Id3 gpis(10, 0, 0); - vtkm::Id3 test_offset(15, 0, 0); - bool includeBoundary = false; - bool includeOffset = true; - cellSet.SetPointDimensions(vtkm::make_Vec(10, 10, 10)); - cellSet.SetGlobalPointIndexStart(gpis); - vtkm::worklet::ExtractStructured worklet; - - auto outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - CellSetType cs = outCellSet.AsCellSet(); - vtkm::Id3 cellDims = cs.GetPointDimensions(); - VTKM_TEST_ASSERT(test_equal(cellDims, test_dims)); - VTKM_TEST_ASSERT(test_equal(cs.GetGlobalPointIndexStart(), test_offset)); - } - - void TestOffset3D3() const - { - std::cout << "Testing Offset 3D-3" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<3>; - CellSetType cellSet; - vtkm::RangeId3 range(100, 110, 0, 10, 0, 10); - vtkm::Id3 sample(1, 1, 1); - vtkm::Id3 test_dims(0, 0, 0); - bool includeBoundary = false; - bool includeOffset = true; - cellSet.SetPointDimensions(vtkm::make_Vec(10, 10, 10)); - vtkm::worklet::ExtractStructured worklet; - - auto outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - CellSetType cs = outCellSet.AsCellSet(); - VTKM_TEST_ASSERT(test_equal(cs.GetPointDimensions(), test_dims)); - } - void TestOffset2D() const - { - std::cout << "Testing offset 2D" << std::endl; - using CellSetType = vtkm::cont::CellSetStructured<2>; - CellSetType cellSet; - // RangeID3 and subsample - vtkm::RangeId3 range(5, 15, 0, 10, 0, 1); - vtkm::Id3 sample(1, 1, 1); - vtkm::Id2 test_offset(10, 0); - vtkm::Id2 no_offset(0, 0); - vtkm::Id2 new_dims(5, 10); - bool includeBoundary = false; - bool includeOffset = false; - cellSet.SetPointDimensions(vtkm::make_Vec(10, 10)); - vtkm::worklet::ExtractStructured worklet; - auto outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - VTKM_TEST_ASSERT(test_equal(cellSet.GetGlobalPointIndexStart(), no_offset)); - vtkm::Id2 cellDims = - outCellSet.AsCellSet().GetSchedulingRange(vtkm::TopologyElementTagCell()); - // Test with offset now - includeOffset = true; - cellSet.SetGlobalPointIndexStart(test_offset); - outCellSet = worklet.Run(cellSet, range, sample, includeBoundary, includeOffset); - cellDims = - outCellSet.AsCellSet().GetSchedulingRange(vtkm::TopologyElementTagCell()); - CellSetType cs = outCellSet.AsCellSet(); - cellDims = cs.GetPointDimensions(); - VTKM_TEST_ASSERT(test_equal(cellDims, new_dims)); - VTKM_TEST_ASSERT(test_equal(cellSet.GetGlobalPointIndexStart(), test_offset)); - } - - void operator()() const - { - TestUniform2D(); - TestUniform3D(); - TestUniform3D1(); - TestRectilinear2D(); - TestRectilinear3D(); - TestOffset3D1(); - TestOffset3D2(); - TestOffset3D3(); - TestOffset2D(); - } -}; - -int UnitTestExtractStructured(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestingExtractStructured(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestFieldHistogram.cxx b/vtkm/worklet/testing/UnitTestFieldHistogram.cxx deleted file mode 100644 index 734cea8dc..000000000 --- a/vtkm/worklet/testing/UnitTestFieldHistogram.cxx +++ /dev/null @@ -1,323 +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 - -// -// Make a simple 2D, 1000 point dataset populated with stat distributions -// -vtkm::cont::DataSet MakeTestDataSet() -{ - vtkm::cont::DataSet dataSet; - - const int dimension = 2; - const int xVerts = 20; - const int yVerts = 50; - const int nVerts = xVerts * yVerts; - - const int xCells = xVerts - 1; - const int yCells = yVerts - 1; - const int nCells = xCells * yCells; - - // Poisson distribution [0:49] mean = 10 - vtkm::Float32 poisson[nVerts] = { - 8, 10, 9, 8, 14, 11, 12, 9, 19, 7, 8, 11, 7, 10, 11, 11, 11, 6, 8, 8, 7, 15, 9, 7, - 8, 10, 9, 10, 10, 12, 7, 6, 14, 10, 14, 10, 7, 11, 13, 9, 13, 11, 10, 10, 12, 12, 7, 12, - 10, 11, 12, 8, 13, 9, 5, 12, 11, 9, 5, 9, 12, 9, 6, 10, 11, 9, 9, 11, 9, 7, 7, 18, - 16, 13, 12, 8, 10, 11, 9, 8, 17, 3, 15, 15, 9, 10, 10, 8, 10, 9, 7, 9, 8, 10, 13, 9, - 7, 11, 7, 10, 13, 10, 11, 9, 10, 7, 10, 6, 12, 6, 9, 7, 6, 12, 12, 9, 12, 12, 11, 6, - 1, 12, 8, 13, 14, 8, 8, 10, 7, 7, 6, 7, 5, 11, 6, 11, 13, 8, 13, 5, 9, 12, 7, 11, - 10, 15, 11, 9, 7, 12, 15, 7, 8, 7, 12, 8, 21, 16, 13, 11, 10, 14, 12, 11, 12, 14, 7, 11, - 7, 12, 16, 8, 10, 8, 9, 7, 8, 7, 13, 13, 11, 15, 7, 7, 6, 11, 7, 12, 12, 13, 14, 11, - 13, 11, 11, 9, 15, 8, 6, 11, 12, 10, 11, 7, 6, 14, 11, 10, 12, 5, 8, 9, 11, 15, 11, 10, - 17, 14, 9, 10, 10, 12, 11, 13, 13, 12, 11, 7, 8, 10, 7, 11, 10, 5, 8, 10, 13, 13, 12, 6, - 10, 7, 13, 8, 11, 7, 10, 7, 8, 7, 14, 16, 9, 11, 8, 11, 9, 15, 11, 10, 10, 12, 7, 7, - 11, 7, 5, 17, 9, 11, 11, 11, 10, 17, 10, 15, 7, 11, 12, 16, 9, 8, 11, 14, 9, 22, 8, 8, - 8, 13, 12, 12, 1, 14, 15, 6, 15, 8, 11, 16, 14, 8, 6, 9, 8, 9, 9, 10, 8, 6, 13, 8, - 6, 12, 11, 12, 13, 8, 6, 6, 5, 6, 10, 9, 11, 12, 14, 12, 10, 11, 10, 10, 8, 13, 8, 11, - 7, 13, 13, 12, 12, 13, 15, 4, 9, 16, 7, 9, 8, 10, 6, 9, 11, 12, 6, 7, 14, 6, 4, 15, - 5, 18, 9, 9, 11, 12, 9, 5, 6, 7, 15, 6, 11, 14, 8, 12, 6, 9, 5, 9, 14, 9, 12, 6, - 9, 14, 11, 12, 12, 13, 15, 9, 8, 7, 13, 12, 7, 13, 6, 9, 10, 10, 10, 9, 11, 5, 9, 13, - 16, 9, 10, 8, 9, 6, 13, 12, 8, 12, 9, 12, 17, 8, 11, 10, 8, 7, 11, 7, 13, 13, 10, 14, - 11, 9, 6, 6, 14, 16, 5, 9, 13, 11, 12, 7, 4, 6, 9, 11, 11, 10, 12, 9, 7, 13, 8, 8, - 12, 5, 10, 7, 11, 11, 10, 10, 14, 6, 8, 8, 3, 12, 16, 11, 11, 7, 6, 12, 11, 5, 9, 12, - 9, 13, 7, 8, 9, 9, 12, 7, 9, 8, 12, 11, 6, 10, 6, 7, 6, 11, 10, 8, 9, 8, 4, 19, - 12, 6, 10, 9, 6, 12, 9, 14, 7, 8, 11, 7, 7, 12, 13, 9, 13, 12, 8, 6, 10, 17, 19, 10, - 10, 13, 5, 11, 8, 10, 8, 16, 12, 6, 6, 7, 10, 9, 12, 8, 5, 10, 7, 18, 9, 12, 10, 4, - 9, 9, 15, 15, 6, 7, 7, 11, 12, 4, 8, 18, 5, 12, 12, 11, 10, 14, 9, 9, 10, 8, 10, 8, - 10, 9, 9, 4, 10, 12, 5, 13, 6, 9, 7, 5, 12, 8, 11, 10, 9, 17, 9, 9, 8, 11, 18, 11, - 10, 9, 4, 13, 10, 15, 5, 10, 9, 7, 7, 8, 10, 6, 6, 19, 10, 16, 7, 7, 9, 10, 10, 13, - 10, 10, 14, 13, 12, 8, 7, 13, 12, 11, 13, 12, 9, 8, 6, 8, 10, 3, 8, 8, 12, 12, 13, 13, - 10, 5, 10, 7, 13, 7, 9, 5, 13, 7, 10, 8, 13, 11, 17, 9, 6, 14, 10, 10, 13, 9, 15, 8, - 15, 9, 12, 11, 12, 8, 3, 9, 8, 10, 12, 8, 14, 13, 12, 11, 12, 9, 18, 10, 13, 7, 4, 4, - 11, 8, 3, 7, 9, 10, 12, 7, 11, 21, 9, 7, 8, 9, 10, 10, 11, 9, 15, 13, 21, 12, 8, 11, - 9, 10, 11, 9, 17, 8, 9, 8, 14, 6, 13, 9, 8, 11, 12, 12, 12, 11, 6, 13, 7, 9, 11, 15, - 17, 17, 11, 10, 7, 8, 11, 8, 6, 9, 13, 7, 9, 6, 5, 10, 7, 16, 16, 9, 7, 6, 14, 8, - 13, 16, 7, 7, 10, 11, 6, 10, 9, 9, 8, 14, 11, 9, 11, 9, 10, 11, 9, 8, 14, 11, 7, 12, - 11, 8, 9, 9, 10, 11, 11, 10, 9, 6, 6, 11, 16, 10, 7, 6, 6, 13, 18, 8, 12, 11, 14, 13, - 8, 8, 10, 17, 17, 6, 6, 10, 18, 5, 8, 11, 6, 6, 14, 10, 9, 6, 11, 6, 13, 12, 10, 6, - 9, 9, 9, 13, 7, 17, 10, 14, 10, 9, 10, 10, 11, 10, 11, 15, 13, 6, 12, 19, 10, 12, 12, 15, - 13, 10, 10, 13, 11, 13, 13, 17, 6, 5, 6, 7, 6, 9, 13, 11, 8, 12, 9, 6, 10, 16, 11, 12, - 5, 12, 14, 13, 13, 16, 11, 6, 12, 12, 15, 8, 7, 11, 8, 5, 10, 8, 9, 11, 9, 12, 10, 5, - 12, 11, 9, 6, 14, 12, 10, 11, 9, 6, 7, 12, 8, 12, 8, 15, 9, 8, 7, 9, 3, 6, 14, 7, - 8, 11, 9, 10, 12, 9, 10, 9, 8, 6, 12, 11, 6, 8, 9, 8, 15, 11, 7, 18, 12, 11, 10, 13, - 11, 11, 10, 7, 9, 8, 8, 11, 11, 13, 6, 12, 13, 16, 11, 11, 5, 12, 14, 15, 9, 14, 15, 6, - 8, 7, 6, 8, 9, 19, 7, 12, 11, 8, 14, 12, 10, 9, 3, 7 - }; - - // Normal distribution [0:49] mean = 25 standard deviation = 5.0 - vtkm::Float32 normal[nVerts] = { - 24, 19, 28, 19, 25, 28, 25, 22, 27, 26, 35, 26, 30, 28, 24, 23, 21, 31, 20, 11, 21, 22, 14, 25, - 20, 24, 24, 21, 24, 29, 26, 21, 32, 29, 23, 28, 31, 25, 23, 30, 18, 24, 22, 25, 33, 24, 22, 23, - 21, 17, 20, 28, 30, 18, 20, 32, 25, 24, 32, 15, 27, 24, 27, 19, 30, 27, 17, 24, 29, 23, 22, 19, - 24, 19, 28, 24, 25, 24, 25, 30, 24, 31, 30, 27, 25, 25, 25, 15, 29, 23, 29, 29, 21, 25, 35, 24, - 28, 10, 31, 23, 22, 22, 22, 33, 29, 27, 18, 27, 27, 24, 20, 20, 21, 29, 23, 31, 23, 23, 22, 23, - 30, 27, 28, 31, 16, 29, 25, 19, 33, 28, 25, 24, 15, 27, 37, 29, 15, 19, 14, 19, 24, 23, 30, 29, - 35, 22, 19, 26, 26, 14, 24, 30, 32, 23, 30, 29, 26, 27, 25, 23, 17, 26, 32, 29, 20, 17, 21, 23, - 22, 20, 36, 12, 26, 23, 15, 29, 24, 22, 26, 33, 24, 23, 20, 26, 22, 17, 26, 26, 34, 22, 26, 17, - 23, 18, 29, 27, 21, 29, 28, 29, 24, 25, 28, 19, 18, 21, 23, 23, 27, 25, 24, 25, 24, 25, 21, 25, - 21, 27, 23, 20, 29, 15, 28, 30, 24, 27, 17, 23, 16, 21, 25, 17, 27, 28, 21, 13, 19, 27, 16, 30, - 31, 25, 30, 17, 17, 25, 26, 22, 21, 17, 24, 17, 25, 22, 27, 14, 27, 24, 27, 25, 26, 31, 21, 23, - 30, 30, 22, 19, 23, 22, 23, 25, 24, 25, 24, 28, 26, 30, 18, 25, 30, 37, 27, 34, 28, 34, 25, 10, - 25, 22, 35, 30, 24, 32, 24, 34, 19, 29, 26, 16, 27, 17, 26, 23, 27, 25, 26, 21, 31, 21, 28, 15, - 32, 24, 23, 23, 18, 15, 22, 25, 16, 25, 31, 26, 25, 28, 24, 26, 23, 25, 33, 20, 27, 28, 24, 29, - 32, 20, 24, 20, 19, 32, 24, 6, 24, 21, 26, 18, 15, 30, 19, 26, 22, 30, 35, 23, 22, 30, 20, 22, - 18, 30, 28, 25, 16, 25, 27, 30, 18, 24, 30, 28, 20, 19, 20, 28, 21, 24, 15, 33, 20, 18, 20, 36, - 30, 26, 25, 18, 28, 27, 31, 31, 15, 26, 16, 22, 27, 14, 17, 27, 27, 22, 32, 30, 22, 34, 22, 25, - 20, 22, 26, 29, 28, 33, 18, 23, 20, 20, 27, 24, 28, 21, 25, 27, 25, 19, 19, 25, 19, 32, 29, 27, - 23, 21, 28, 33, 23, 23, 28, 26, 31, 19, 21, 29, 21, 27, 23, 32, 24, 26, 21, 28, 28, 24, 17, 31, - 27, 21, 19, 32, 28, 23, 30, 23, 29, 15, 26, 26, 15, 20, 25, 26, 27, 31, 21, 23, 23, 33, 28, 19, - 23, 22, 22, 25, 27, 17, 23, 17, 25, 28, 26, 30, 32, 31, 19, 25, 25, 19, 23, 29, 27, 23, 34, 22, - 13, 21, 32, 10, 20, 33, 21, 17, 29, 31, 14, 24, 23, 19, 19, 22, 17, 26, 37, 26, 22, 26, 38, 29, - 29, 27, 30, 20, 31, 14, 32, 32, 24, 23, 23, 18, 21, 31, 24, 20, 28, 15, 21, 25, 25, 20, 30, 25, - 22, 21, 21, 25, 24, 25, 18, 23, 28, 30, 20, 27, 27, 19, 10, 32, 24, 20, 29, 26, 25, 20, 25, 29, - 28, 24, 32, 26, 22, 19, 23, 27, 27, 29, 20, 25, 21, 30, 28, 31, 24, 19, 23, 19, 19, 18, 30, 18, - 16, 24, 20, 20, 30, 25, 29, 25, 31, 21, 28, 31, 24, 26, 27, 21, 24, 23, 26, 18, 32, 26, 28, 26, - 24, 26, 29, 30, 22, 20, 24, 28, 25, 29, 20, 21, 22, 15, 30, 27, 33, 26, 22, 32, 30, 31, 20, 19, - 24, 26, 27, 31, 17, 17, 33, 27, 16, 27, 27, 22, 27, 19, 24, 21, 17, 24, 28, 23, 26, 24, 19, 26, - 20, 24, 22, 19, 22, 21, 21, 28, 29, 39, 19, 16, 25, 29, 31, 22, 22, 29, 26, 22, 22, 22, 26, 23, - 23, 23, 30, 25, 25, 25, 27, 29, 18, 33, 21, 12, 22, 29, 12, 20, 35, 22, 34, 28, 18, 29, 21, 20, - 24, 33, 24, 26, 23, 34, 31, 25, 31, 22, 35, 21, 20, 29, 27, 22, 30, 22, 27, 23, 22, 32, 16, 19, - 27, 22, 24, 27, 21, 33, 25, 25, 19, 28, 20, 27, 21, 25, 28, 20, 27, 22, 21, 20, 26, 30, 33, 23, - 20, 24, 17, 23, 28, 35, 14, 23, 22, 28, 28, 26, 25, 18, 20, 28, 28, 22, 13, 24, 22, 20, 30, 26, - 26, 18, 22, 20, 23, 24, 20, 27, 34, 28, 18, 24, 34, 33, 25, 33, 37, 21, 20, 31, 19, 23, 29, 22, - 21, 24, 19, 27, 19, 32, 25, 23, 33, 26, 33, 27, 29, 30, 19, 22, 30, 19, 18, 24, 25, 17, 31, 19, - 31, 26, 22, 23, 28, 28, 25, 24, 19, 19, 27, 28, 23, 21, 29, 26, 31, 22, 22, 25, 16, 29, 21, 22, - 23, 25, 22, 21, 22, 19, 27, 26, 28, 30, 22, 21, 24, 22, 23, 26, 28, 22, 18, 25, 23, 27, 31, 19, - 15, 29, 20, 19, 27, 25, 21, 29, 22, 24, 25, 17, 36, 29, 22, 22, 24, 28, 27, 22, 26, 31, 29, 31, - 18, 25, 23, 16, 37, 27, 21, 31, 25, 24, 20, 23, 28, 33, 24, 21, 26, 20, 18, 31, 20, 24, 23, 19, - 27, 17, 23, 23, 20, 26, 28, 23, 26, 31, 25, 31, 19, 32, 26, 18, 19, 29, 20, 21, 15, 25, 27, 29, - 22, 22, 22, 26, 23, 22, 23, 29, 28, 20, 21, 22, 20, 22, 27, 25, 23, 32, 23, 20, 31, 20, 27, 26, - 34, 20, 22, 36, 21, 29, 25, 20, 21, 22, 29, 29, 25, 22, 24, 22 - }; - - //Chi squared distribution [0:49] degrees of freedom = 5.0 - vtkm::Float32 chiSquare[nVerts] = { - 3, 1, 4, 6, 5, 4, 8, 7, 2, 9, 2, 0, 0, 4, 3, 2, 5, 2, 3, 6, 3, 8, 3, 4, - 3, 3, 2, 7, 2, 10, 9, 6, 1, 1, 4, 7, 3, 3, 1, 4, 4, 3, 9, 4, 4, 7, 3, 2, - 4, 7, 3, 3, 2, 10, 1, 6, 2, 2, 3, 8, 3, 3, 6, 9, 4, 1, 4, 3, 16, 7, 0, 1, - 8, 7, 13, 3, 5, 0, 3, 8, 10, 3, 5, 5, 1, 5, 2, 1, 3, 2, 5, 3, 4, 3, 3, 3, - 3, 1, 13, 2, 3, 1, 2, 7, 3, 4, 1, 2, 5, 4, 4, 4, 2, 6, 3, 2, 7, 8, 1, 3, - 4, 1, 2, 0, 1, 6, 1, 8, 8, 1, 1, 4, 2, 1, 4, 3, 5, 4, 6, 4, 2, 3, 8, 8, - 3, 3, 3, 4, 5, 8, 8, 16, 7, 12, 4, 3, 14, 8, 3, 12, 5, 0, 5, 3, 5, 2, 9, 2, - 9, 4, 1, 0, 0, 4, 4, 6, 3, 4, 11, 2, 4, 7, 4, 2, 1, 9, 4, 3, 2, 5, 1, 5, - 3, 8, 2, 8, 1, 8, 0, 4, 1, 3, 2, 1, 2, 3, 2, 1, 8, 5, 4, 1, 9, 9, 1, 3, - 5, 0, 1, 6, 10, 8, 3, 12, 3, 4, 4, 7, 1, 3, 6, 4, 4, 6, 1, 4, 7, 5, 6, 11, - 6, 5, 2, 7, 2, 5, 3, 5, 6, 3, 6, 2, 1, 10, 8, 3, 7, 0, 2, 6, 9, 3, 11, 3, - 2, 5, 1, 4, 6, 10, 9, 1, 4, 3, 7, 12, 3, 10, 0, 2, 11, 2, 1, 0, 4, 1, 2, 16, - 5, 17, 7, 8, 2, 10, 10, 3, 1, 3, 2, 2, 4, 8, 4, 3, 2, 4, 4, 6, 8, 6, 2, 3, - 2, 4, 2, 4, 7, 10, 5, 3, 5, 2, 4, 6, 9, 3, 1, 1, 1, 1, 4, 2, 2, 7, 4, 9, - 2, 3, 5, 6, 2, 5, 1, 6, 5, 7, 8, 3, 7, 2, 2, 8, 6, 2, 10, 2, 1, 4, 5, 1, - 1, 1, 5, 6, 1, 1, 4, 5, 4, 2, 4, 3, 2, 7, 19, 4, 7, 2, 7, 5, 2, 5, 3, 8, - 4, 6, 7, 2, 0, 0, 2, 12, 6, 2, 2, 3, 5, 9, 4, 9, 2, 2, 7, 8, 3, 3, 10, 6, - 3, 2, 1, 6, 2, 4, 6, 3, 5, 8, 2, 3, 6, 14, 0, 3, 6, 5, 2, 7, 0, 3, 8, 5, - 3, 2, 2, 5, 1, 3, 12, 11, 16, 2, 1, 3, 7, 3, 1, 6, 4, 3, 12, 5, 1, 3, 1, 4, - 9, 1, 3, 3, 4, 4, 6, 7, 7, 5, 2, 4, 2, 3, 2, 2, 6, 4, 2, 2, 3, 5, 1, 4, - 9, 1, 0, 7, 6, 4, 3, 3, 7, 3, 3, 6, 2, 7, 9, 3, 1, 16, 5, 4, 3, 6, 3, 2, - 5, 2, 2, 4, 3, 1, 3, 3, 6, 3, 5, 9, 1, 10, 1, 7, 2, 2, 6, 7, 3, 5, 3, 7, - 2, 2, 2, 2, 6, 4, 3, 2, 5, 5, 3, 15, 4, 2, 7, 7, 4, 3, 3, 5, 1, 2, 9, 0, - 5, 7, 12, 2, 4, 8, 5, 7, 8, 3, 2, 2, 18, 1, 7, 2, 2, 1, 3, 3, 3, 7, 1, 9, - 8, 4, 3, 7, 6, 4, 5, 2, 0, 5, 1, 5, 10, 4, 2, 8, 2, 2, 0, 5, 6, 4, 5, 0, - 1, 5, 11, 3, 3, 4, 4, 2, 3, 5, 1, 6, 5, 7, 2, 2, 5, 7, 4, 8, 4, 1, 1, 7, - 2, 3, 9, 6, 13, 1, 5, 4, 6, 2, 4, 11, 2, 5, 5, 1, 4, 1, 4, 7, 1, 5, 8, 3, - 1, 10, 9, 13, 1, 7, 2, 9, 4, 3, 3, 10, 12, 2, 0, 4, 6, 5, 5, 1, 4, 7, 2, 12, - 7, 6, 5, 0, 6, 4, 4, 12, 1, 3, 10, 1, 9, 2, 2, 2, 1, 5, 5, 6, 9, 6, 4, 1, - 11, 6, 9, 3, 2, 7, 1, 7, 4, 3, 0, 3, 1, 12, 17, 2, 1, 6, 4, 4, 2, 1, 5, 5, - 3, 2, 2, 4, 6, 5, 4, 6, 11, 3, 12, 6, 3, 6, 3, 0, 6, 3, 7, 4, 8, 5, 14, 5, - 1, 9, 4, 6, 5, 3, 9, 3, 1, 1, 0, 3, 7, 3, 5, 1, 6, 2, 2, 6, 2, 12, 1, 0, - 6, 3, 3, 5, 4, 7, 2, 2, 15, 7, 3, 10, 4, 2, 6, 3, 4, 8, 3, 1, 5, 5, 5, 4, - 3, 7, 3, 4, 5, 5, 2, 4, 2, 5, 1, 12, 5, 6, 3, 2, 8, 5, 2, 3, 11, 11, 6, 5, - 0, 3, 3, 9, 4, 2, 11, 1, 5, 3, 5, 6, 3, 6, 4, 2, 4, 10, 11, 3, 3, 4, 1, 1, - 1, 3, 5, 5, 1, 1, 4, 1, 5, 1, 6, 8, 6, 4, 6, 7, 6, 3, 5, 3, 6, 6, 6, 4, - 0, 6, 3, 1, 2, 4, 2, 6, 1, 1, 1, 2, 2, 4, 7, 2, 6, 2, 5, 7, 6, 4, 6, 3, - 1, 4, 5, 1, 4, 6, 2, 3, 0, 6, 11, 2, 9, 2, 6, 4, 5, 6, 2, 19, 2, 10, 4, 2, - 3, 3, 11, 7, 3, 3, 1, 5, 3, 6, 4, 3, 0, 6, 6, 6, 4, 2, 5, 2, 2, 2, 6, 10, - 4, 9, 3, 7, 7, 0, 6, 8, 5, 2, 3, 2, 3, 3, 3, 1, 6, 1, 8, 2, 5, 3, 6, 11, - 5, 7, 2, 6, 7, 3, 4, 1, 0, 5, 8, 3, 2, 9, 3, 1, 2, 3, 3, 9, 5, 6, 5, 1, - 4, 5, 6, 7, 6, 1, 5, 1, 6, 6, 2, 6, 7, 2, 4, 6 - }; - - // Uniform distribution [0:49] - vtkm::Float32 uniform[nVerts] = { - 0, 6, 37, 22, 26, 10, 2, 33, 33, 46, 19, 25, 41, 1, 2, 26, 33, 0, 19, 3, 20, 34, 29, 46, - 42, 26, 4, 32, 20, 35, 45, 38, 13, 2, 36, 16, 31, 37, 49, 18, 12, 49, 36, 37, 32, 3, 31, 44, - 13, 21, 38, 23, 11, 13, 17, 8, 24, 44, 45, 3, 45, 25, 25, 15, 49, 24, 13, 4, 47, 3, 25, 19, - 13, 45, 26, 23, 47, 2, 38, 38, 41, 6, 0, 34, 43, 31, 36, 36, 49, 44, 11, 15, 17, 25, 29, 42, - 20, 42, 13, 20, 26, 23, 14, 8, 7, 28, 40, 1, 26, 24, 47, 37, 27, 44, 31, 42, 7, 10, 35, 6, - 4, 13, 0, 20, 1, 35, 46, 11, 9, 15, 44, 32, 7, 34, 19, 19, 24, 7, 29, 42, 29, 47, 27, 7, - 49, 20, 7, 28, 12, 24, 23, 48, 6, 9, 15, 31, 6, 32, 31, 40, 12, 23, 19, 10, 1, 45, 21, 7, - 47, 20, 6, 44, 4, 8, 3, 18, 12, 6, 39, 22, 17, 22, 40, 46, 32, 10, 33, 45, 12, 43, 23, 25, - 30, 40, 37, 23, 47, 31, 21, 41, 34, 35, 49, 47, 42, 14, 26, 25, 5, 20, 28, 43, 22, 36, 43, 35, - 40, 35, 37, 0, 44, 26, 23, 3, 35, 24, 33, 34, 9, 45, 43, 44, 27, 6, 22, 49, 10, 22, 15, 25, - 44, 21, 23, 40, 18, 10, 49, 7, 31, 30, 0, 0, 38, 36, 15, 20, 34, 34, 10, 41, 35, 41, 4, 4, - 38, 31, 10, 10, 4, 19, 47, 47, 19, 13, 34, 14, 38, 39, 21, 14, 9, 0, 9, 49, 12, 40, 6, 19, - 30, 8, 41, 7, 49, 12, 11, 5, 10, 31, 34, 39, 34, 37, 33, 31, 2, 29, 11, 15, 34, 5, 38, 26, - 27, 29, 16, 35, 7, 8, 24, 43, 40, 27, 36, 15, 6, 26, 15, 29, 25, 21, 12, 18, 19, 22, 23, 19, - 13, 3, 18, 12, 33, 33, 25, 36, 36, 47, 23, 47, 16, 23, 25, 33, 20, 30, 49, 7, 33, 17, 27, 26, - 41, 0, 13, 32, 27, 45, 13, 48, 12, 42, 34, 22, 40, 1, 8, 35, 35, 21, 29, 37, 49, 34, 13, 37, - 8, 0, 24, 3, 8, 45, 39, 37, 21, 0, 29, 25, 3, 27, 19, 10, 19, 31, 32, 35, 26, 14, 40, 18, - 34, 15, 0, 5, 26, 38, 11, 2, 3, 8, 36, 14, 2, 23, 22, 25, 22, 7, 14, 41, 34, 28, 34, 16, - 2, 49, 27, 0, 42, 1, 18, 24, 28, 36, 33, 26, 1, 6, 48, 9, 17, 30, 30, 6, 27, 47, 17, 41, - 48, 12, 12, 21, 40, 44, 12, 38, 34, 22, 13, 33, 5, 10, 5, 27, 0, 8, 29, 21, 4, 34, 18, 41, - 6, 48, 1, 4, 24, 38, 46, 12, 17, 38, 24, 37, 33, 34, 37, 1, 11, 11, 28, 32, 30, 18, 11, 11, - 32, 8, 37, 7, 2, 33, 6, 47, 24, 31, 45, 0, 29, 36, 24, 2, 22, 25, 38, 3, 22, 48, 23, 16, - 22, 37, 10, 8, 18, 46, 48, 12, 3, 6, 26, 8, 25, 5, 42, 18, 21, 16, 35, 28, 43, 37, 41, 34, - 19, 46, 30, 18, 26, 22, 20, 12, 4, 21, 23, 14, 5, 10, 40, 26, 33, 43, 12, 35, 13, 19, 4, 22, - 11, 39, 24, 0, 13, 33, 21, 9, 48, 6, 39, 47, 8, 30, 3, 17, 14, 25, 41, 41, 36, 16, 40, 31, - 2, 2, 7, 38, 3, 25, 46, 11, 10, 4, 34, 35, 24, 13, 35, 18, 10, 11, 21, 23, 43, 48, 22, 1, - 26, 1, 37, 29, 41, 16, 11, 26, 21, 20, 49, 48, 42, 43, 15, 7, 49, 31, 23, 46, 34, 40, 27, 28, - 7, 47, 41, 7, 2, 17, 5, 4, 25, 1, 28, 42, 25, 33, 36, 34, 1, 9, 33, 17, 3, 7, 46, 11, - 19, 29, 8, 1, 34, 38, 35, 3, 29, 46, 46, 21, 25, 41, 45, 30, 36, 25, 24, 8, 48, 28, 13, 26, - 34, 33, 4, 27, 30, 33, 24, 28, 29, 22, 7, 25, 36, 1, 2, 26, 16, 1, 12, 5, 19, 27, 29, 30, - 46, 38, 25, 24, 32, 34, 20, 24, 23, 35, 26, 13, 30, 14, 35, 26, 46, 11, 20, 29, 39, 46, 34, 41, - 26, 11, 7, 44, 12, 32, 0, 46, 13, 42, 13, 47, 25, 6, 20, 35, 21, 5, 38, 4, 22, 17, 14, 37, - 16, 16, 2, 28, 24, 10, 5, 48, 43, 24, 18, 40, 8, 7, 2, 7, 23, 19, 44, 21, 20, 32, 15, 3, - 40, 44, 45, 45, 38, 8, 28, 1, 40, 26, 43, 13, 43, 29, 19, 40, 26, 46, 21, 28, 37, 44, 16, 9, - 37, 35, 43, 3, 35, 43, 17, 4, 8, 20, 4, 33, 28, 40, 43, 38, 31, 44, 43, 24, 5, 18, 19, 34, - 6, 3, 7, 23, 35, 11, 19, 48, 31, 34, 45, 18, 42, 39, 21, 3, 24, 24, 22, 24, 37, 46, 15, 7, - 5, 4, 48, 20, 11, 48, 41, 9, 6, 9, 16, 28, 22, 29, 21, 18, 19, 30, 21, 7, 33, 49, 34, 20, - 42, 40, 39, 18, 0, 23, 31, 32, 32, 39, 18, 17, 19, 16, 34, 7, 14, 33, 42, 15, 7, 30, 0, 46, - 19, 25, 17, 13, 14, 41, 6, 31, 2, 22, 18, 7, 37, 33, 0, 39, 28, 14, 20, 16, 25, 35, 42, 11, - 23, 18, 2, 3, 10, 28, 41, 21, 41, 14, 9, 17, 46, 29, 18, 23, 31, 47, 20, 2, 22, 29, 37, 43, - 6, 5, 33, 41, 29, 32, 49, 0, 46, 9, 48, 26, 13, 35, 29, 41, 41, 32, 36, 32, 17, 26, 33, 16, - 43, 22, 45, 13, 47, 5, 20, 41, 48, 16, 26, 26, 40, 46, 33, 12 - }; - - vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vtkm::Id3(xVerts, yVerts, 1)); - dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates)); - - // Set point scalars - dataSet.AddField(vtkm::cont::make_Field( - "p_poisson", vtkm::cont::Field::Association::POINTS, poisson, nVerts, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "p_normal", vtkm::cont::Field::Association::POINTS, normal, nVerts, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "p_chiSquare", vtkm::cont::Field::Association::POINTS, chiSquare, nVerts, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "p_uniform", vtkm::cont::Field::Association::POINTS, uniform, nVerts, vtkm::CopyFlag::On)); - - // Set cell scalars - dataSet.AddField(vtkm::cont::make_Field( - "c_poisson", vtkm::cont::Field::Association::CELL_SET, poisson, nCells, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "c_normal", vtkm::cont::Field::Association::CELL_SET, normal, nCells, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field("c_chiSquare", - vtkm::cont::Field::Association::CELL_SET, - chiSquare, - nCells, - vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "c_uniform", vtkm::cont::Field::Association::CELL_SET, poisson, nCells, vtkm::CopyFlag::On)); - - vtkm::cont::CellSetStructured cellSet; - - //Set regular structure - cellSet.SetPointDimensions(vtkm::make_Vec(xVerts, yVerts)); - dataSet.SetCellSet(cellSet); - - return dataSet; -} - -// -// Print the histogram result and tally -// -void PrintHistogram(vtkm::cont::ArrayHandle bins, - vtkm::Id numberOfBins, - const vtkm::Range& range, - vtkm::Float32 delta) -{ - vtkm::cont::ArrayHandle::ReadPortalType binPortal = bins.ReadPortal(); - - vtkm::Id sum = 0; - for (vtkm::Id i = 0; i < numberOfBins; i++) - { - vtkm::Float64 lo = range.Min + (static_cast(i) * delta); - vtkm::Float64 hi = lo + delta; - sum += binPortal.Get(i); - std::cout << " BIN[" << i << "] Range[" << lo << ", " << hi << "] = " << binPortal.Get(i) - << std::endl; - } - VTKM_TEST_ASSERT(test_equal(sum, 1000), "Histogram not full"); -} - -// -// Create a dataset with known point data and cell data (statistical distributions) -// Extract arrays of point and cell fields -// Create output structure to hold histogram bins -// Run FieldHistogram filter -// -void TestFieldHistogram() -{ - // Create the output bin array - vtkm::Id numberOfBins = 10; - vtkm::Range range; - vtkm::Float32 delta; - vtkm::cont::ArrayHandle bins; - bins.Allocate(numberOfBins); - - // Data attached is the poisson distribution - vtkm::cont::DataSet ds = MakeTestDataSet(); - - // Get point data - vtkm::cont::ArrayHandle p_poisson; - ds.GetField("p_poisson").GetData().AsArrayHandle(p_poisson); - vtkm::cont::ArrayHandle p_normal; - ds.GetField("p_normal").GetData().AsArrayHandle(p_normal); - vtkm::cont::ArrayHandle p_chiSquare; - ds.GetField("p_chiSquare").GetData().AsArrayHandle(p_chiSquare); - vtkm::cont::ArrayHandle p_uniform; - ds.GetField("p_uniform").GetData().AsArrayHandle(p_uniform); - - vtkm::worklet::FieldHistogram histogram; - // Run data - histogram.Run(p_poisson, numberOfBins, range, delta, bins); - std::cout << "Poisson distributed POINT data:" << std::endl; - PrintHistogram(bins, numberOfBins, range, delta); - - histogram.Run(p_normal, numberOfBins, range, delta, bins); - std::cout << "Normal distributed POINT data:" << std::endl; - PrintHistogram(bins, numberOfBins, range, delta); - - histogram.Run(p_chiSquare, numberOfBins, range, delta, bins); - std::cout << "Chi Square distributed POINT data:" << std::endl; - PrintHistogram(bins, numberOfBins, range, delta); - - histogram.Run(p_uniform, numberOfBins, range, delta, bins); - std::cout << "Uniform distributed POINT data:" << std::endl; - PrintHistogram(bins, numberOfBins, range, delta); -} // TestFieldHistogram - -int UnitTestFieldHistogram(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestFieldHistogram, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestGraphConnectivity.cxx b/vtkm/worklet/testing/UnitTestGraphConnectivity.cxx deleted file mode 100644 index 7be3fc316..000000000 --- a/vtkm/worklet/testing/UnitTestGraphConnectivity.cxx +++ /dev/null @@ -1,141 +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 - -class AdjacentDifference : public vtkm::worklet::WorkletMapField -{ -public: - using ControlSignature = void(FieldIn index, WholeArrayIn counts, FieldOut outputCount); - using ExecutionSignature = void(_1, _2, _3); - using InputDomain = _1; - - template - VTKM_EXEC void operator()(const vtkm::Id& index, - const WholeArrayType& counts, - int& difference) const - { - difference = counts.Get(index + 1) - counts.Get(index); - } -}; - -class SameComponent : public vtkm::worklet::WorkletMapField -{ -public: - using ControlSignature = void(FieldIn start, - FieldIn degree, - WholeArrayIn conns, - WholeArrayIn comps, - AtomicArrayInOut same); - using ExecutionSignature = void(WorkIndex, _1, _2, _3, _4, _5); - - template - VTKM_EXEC void operator()(vtkm::Id index, - int start, - int degree, - const Conn& conns, - const Comp& comps, - AtomicSame& same) const - { - for (vtkm::Id offset = start; offset < start + degree; ++offset) - { - vtkm::Id neighbor = conns.Get(offset); - if (comps.Get(index) != comps.Get(neighbor)) - { - same.Set(0, 0); - } - } - } -}; - -class TestGraphConnectivity -{ -public: - void TestECL_CC(const std::string& filename, int ncomps) const - { - auto pathname = - vtkm::cont::testing::Testing::GetTestDataBasePath() + "/third_party/ecl_cc/" + filename; - std::ifstream stream(pathname, std::ios_base::in | std::ios_base::binary); - - int nnodes; - stream.read(reinterpret_cast(&nnodes), sizeof(nnodes)); - - int nedges; - stream.read(reinterpret_cast(&nedges), sizeof(nedges)); - - // CSR, there is one more element in offsets thant the actual number of nodes. - std::vector offsets(nnodes + 1); - std::vector conns(nedges); - - stream.read(reinterpret_cast(offsets.data()), (nnodes + 1) * sizeof(int)); - stream.read(reinterpret_cast(conns.data()), nedges * sizeof(int)); - - vtkm::cont::ArrayHandle counts_h; - vtkm::cont::Invoker invoke; - invoke(AdjacentDifference{}, - vtkm::cont::make_ArrayHandleCounting(0, 1, nnodes), - vtkm::cont::make_ArrayHandle(offsets, vtkm::CopyFlag::On), - counts_h); - - offsets.pop_back(); - vtkm::cont::ArrayHandle offsets_h = - vtkm::cont::make_ArrayHandle(offsets, vtkm::CopyFlag::On); - - vtkm::cont::ArrayHandle conns_h = vtkm::cont::make_ArrayHandle(conns, vtkm::CopyFlag::Off); - - vtkm::cont::ArrayHandle comps_h; - vtkm::worklet::connectivity::GraphConnectivity().Run(counts_h, offsets_h, conns_h, comps_h); - - VTKM_TEST_ASSERT(vtkm::cont::Algorithm::Reduce(comps_h, vtkm::Id(0), vtkm::Maximum{}) == - ncomps - 1, - "number of components mismatch"); - - vtkm::cont::ArrayHandle atomicSame; - atomicSame.Allocate(1); - atomicSame.WritePortal().Set(0, 1); - - invoke(SameComponent{}, offsets_h, counts_h, conns_h, comps_h, atomicSame); - VTKM_TEST_ASSERT(atomicSame.ReadPortal().Get(0) == 1, - "Neighboring nodes don't have the same component id"); - } - - void TestECL_CC_DataSets() const { TestECL_CC("internet.egr", 1); } - - void TestSimpleGraph() const - { - vtkm::cont::ArrayHandle counts_h = - vtkm::cont::make_ArrayHandle({ 1, 1, 2, 2, 2 }); - vtkm::cont::ArrayHandle offsets_h = - vtkm::cont::make_ArrayHandle({ 0, 1, 2, 4, 6 }); - vtkm::cont::ArrayHandle conn_h = - vtkm::cont::make_ArrayHandle({ 2, 4, 0, 3, 2, 4, 1, 3 }); - vtkm::cont::ArrayHandle comps; - - vtkm::worklet::connectivity::GraphConnectivity().Run(counts_h, offsets_h, conn_h, comps); - - for (int i = 0; i < comps.GetNumberOfValues(); i++) - { - VTKM_TEST_ASSERT(comps.ReadPortal().Get(i) == 0, "Components has unexpected value."); - } - } - - void operator()() const - { - TestSimpleGraph(); - TestECL_CC_DataSets(); - } -}; - -int UnitTestGraphConnectivity(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestGraphConnectivity(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestImageConnectivity.cxx b/vtkm/worklet/testing/UnitTestImageConnectivity.cxx deleted file mode 100644 index 70fae1ddb..000000000 --- a/vtkm/worklet/testing/UnitTestImageConnectivity.cxx +++ /dev/null @@ -1,148 +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 - -class TestImageConnectivity -{ -public: - using Algorithm = vtkm::cont::Algorithm; - - void operator()() const - { - CCL_CUDA8x4(); - CCL_CUDA8x8(); - Valentine(); - } - - void CCL_CUDA8x4() const - { - // example image from Connected Component Labeling in CUDA by OndˇrejˇŚtava, - // Bedˇrich Beneˇ - std::vector pixels(8 * 4, 0); - pixels[3] = pixels[4] = pixels[10] = pixels[11] = 1; - pixels[1] = pixels[9] = pixels[16] = pixels[17] = pixels[24] = pixels[25] = 1; - pixels[7] = pixels[15] = pixels[21] = pixels[23] = pixels[28] = pixels[29] = pixels[30] = - pixels[31] = 1; - - vtkm::cont::DataSetBuilderUniform builder; - vtkm::cont::DataSet data = builder.Create(vtkm::Id3(8, 4, 1)); - - auto colorField = vtkm::cont::make_FieldPoint( - "color", vtkm::cont::make_ArrayHandle(pixels, vtkm::CopyFlag::On)); - data.AddField(colorField); - - vtkm::cont::ArrayHandle component; - vtkm::worklet::connectivity::ImageConnectivity().Run( - data.GetCellSet().AsCellSet>(), - colorField.GetData().AsArrayHandle>(), - component); - - std::vector componentExpected = { 0, 1, 2, 1, 1, 3, 3, 4, 0, 1, 1, 1, 3, 3, 3, 4, - 1, 1, 3, 3, 3, 4, 3, 4, 1, 1, 3, 3, 4, 4, 4, 4 }; - - - std::size_t i = 0; - for (vtkm::Id index = 0; index < component.GetNumberOfValues(); index++, i++) - { - VTKM_TEST_ASSERT(component.ReadPortal().Get(index) == componentExpected[i], - "Components has unexpected value."); - } - } - - void CCL_CUDA8x8() const - { - // example from Figure 35.7 of Connected Component Labeling in CUDA by OndˇrejˇŚtava, - // Bedˇrich Beneˇ - auto pixels = vtkm::cont::make_ArrayHandle({ - 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, - 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, - }); - - vtkm::cont::DataSetBuilderUniform builder; - vtkm::cont::DataSet data = builder.Create(vtkm::Id3(8, 8, 1)); - - auto colorField = vtkm::cont::make_FieldPoint("color", pixels); - data.AddField(colorField); - - vtkm::cont::ArrayHandle component; - vtkm::worklet::connectivity::ImageConnectivity().Run( - data.GetCellSet().AsCellSet>(), - colorField.GetData().AsArrayHandle>(), - component); - - std::vector componentExpected = { 0, 1, 1, 1, 0, 1, 1, 2, 0, 0, 0, 1, 0, 1, 1, 2, - 0, 1, 1, 0, 0, 1, 1, 2, 0, 1, 0, 0, 0, 1, 1, 2, - 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, - 0, 1, 0, 1, 1, 1, 3, 3, 0, 1, 1, 1, 1, 1, 3, 3 }; - - for (vtkm::Id i = 0; i < component.GetNumberOfValues(); ++i) - { - VTKM_TEST_ASSERT(component.ReadPortal().Get(i) == componentExpected[size_t(i)], - "Components has unexpected value."); - } - } - - void Valentine() const - { - // Sample image by VALENTINE PELTIER - - // clang-format off - auto pixels = vtkm::cont::make_ArrayHandle( { - 1, 1, 0, 1, 0, 0, - 0, 0, 0, 1, 1, 0, - 1, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 0, 0, - 0, 1, 0, 1, 1, 1, - 1, 1, 0, 0, 1, 0, - }); - // clang-format on - - vtkm::cont::DataSetBuilderUniform builder; - vtkm::cont::DataSet data = builder.Create(vtkm::Id3(6, 6, 1)); - - auto colorField = vtkm::cont::make_FieldPoint("color", pixels); - data.AddField(colorField); - - vtkm::cont::ArrayHandle component; - vtkm::worklet::connectivity::ImageConnectivity().Run( - data.GetCellSet().AsCellSet>(), - colorField.GetData().AsArrayHandle>(), - component); - - // clang-format off - std::vector componentExpected = { - 0, 0, 1, 2, 1, 1, - 1, 1, 1, 2, 2, 1, - 2, 2, 1, 2, 1, 2, - 2, 1, 2, 1, 1, 1, - 1, 2, 1, 2, 2, 2, - 2, 2, 1, 1, 2, 3 - }; - // clang-format on - - for (vtkm::Id i = 0; i < component.GetNumberOfValues(); ++i) - { - VTKM_TEST_ASSERT(component.ReadPortal().Get(i) == componentExpected[size_t(i)], - "Components has unexpected value."); - } - } -}; - - -int UnitTestImageConnectivity(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestImageConnectivity(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestInnerJoin.cxx b/vtkm/worklet/testing/UnitTestInnerJoin.cxx deleted file mode 100644 index 59bb00453..000000000 --- a/vtkm/worklet/testing/UnitTestInnerJoin.cxx +++ /dev/null @@ -1,96 +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 - - -class TestInnerJoin -{ -public: - static bool TestJoinedValues(const vtkm::cont::ArrayHandle& computedValuesArray, - const vtkm::cont::ArrayHandle& expectedValuesArray, - const vtkm::cont::ArrayHandle& originalKeysArray) - { - auto computedValues = computedValuesArray.ReadPortal(); - auto expectedValues = expectedValuesArray.ReadPortal(); - auto originalKeys = originalKeysArray.ReadPortal(); - if (computedValues.GetNumberOfValues() != expectedValues.GetNumberOfValues()) - { - return false; - } - - for (vtkm::Id valueIndex = 0; valueIndex < computedValues.GetNumberOfValues(); ++valueIndex) - { - vtkm::Id computed = computedValues.Get(valueIndex); - vtkm::Id expected = expectedValues.Get(valueIndex); - - // The join algorithm uses some key/value sorts that are unstable. Thus, for keys - // that are repeated in the original input, the computed and expected values may be - // swapped in the results associated with those keys. To test correctly, the values - // we computed for are actually indices into the original keys array. Thus, if both - // computed and expected are different indices that point to the same original key, - // then the algorithm is still correct. - vtkm::Id computedKey = originalKeys.Get(computed); - vtkm::Id expectedKey = originalKeys.Get(expected); - if (computedKey != expectedKey) - { - return false; - } - } - - return true; - } - - void TestTwoArrays() const - { - vtkm::cont::ArrayHandle keysAOriginal = - vtkm::cont::make_ArrayHandle({ 8, 3, 6, 8, 9, 5, 12, 10, 14 }); - vtkm::cont::ArrayHandle keysBOriginal = - vtkm::cont::make_ArrayHandle({ 7, 11, 9, 8, 5, 1, 0, 5 }); - - vtkm::cont::ArrayHandle keysA; - vtkm::cont::ArrayHandle keysB; - vtkm::cont::ArrayHandle valuesA; - vtkm::cont::ArrayHandle valuesB; - - vtkm::cont::ArrayCopy(keysAOriginal, keysA); - vtkm::cont::ArrayCopy(keysBOriginal, keysB); - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(keysA.GetNumberOfValues()), valuesA); - vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(keysB.GetNumberOfValues()), valuesB); - - vtkm::cont::ArrayHandle joinedIndex; - vtkm::cont::ArrayHandle outA; - vtkm::cont::ArrayHandle outB; - - vtkm::worklet::connectivity::InnerJoin().Run( - keysA, valuesA, keysB, valuesB, joinedIndex, outA, outB); - - vtkm::cont::ArrayHandle expectedIndex = - vtkm::cont::make_ArrayHandle({ 5, 5, 8, 8, 9 }); - VTKM_TEST_ASSERT(test_equal_portals(joinedIndex.ReadPortal(), expectedIndex.ReadPortal())); - - vtkm::cont::ArrayHandle expectedOutA = - vtkm::cont::make_ArrayHandle({ 5, 5, 0, 3, 4 }); - VTKM_TEST_ASSERT(TestJoinedValues(outA, expectedOutA, keysAOriginal)); - - vtkm::cont::ArrayHandle expectedOutB = - vtkm::cont::make_ArrayHandle({ 4, 7, 3, 3, 2 }); - VTKM_TEST_ASSERT(TestJoinedValues(outB, expectedOutB, keysBOriginal)); - } - - void operator()() const { this->TestTwoArrays(); } -}; - -int UnitTestInnerJoin(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestInnerJoin(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestMask.cxx b/vtkm/worklet/testing/UnitTestMask.cxx deleted file mode 100644 index e943789b2..000000000 --- a/vtkm/worklet/testing/UnitTestMask.cxx +++ /dev/null @@ -1,119 +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 -#include -#include - -using vtkm::cont::testing::MakeTestDataSet; - -class TestingMask -{ -public: - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestUniform2D() const - { - std::cout << "Testing mask cells structured:" << std::endl; - - using CellSetType = vtkm::cont::CellSetStructured<2>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet1(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Output data set permutation - vtkm::worklet::Mask maskCells; - OutCellSetType outCellSet = maskCells.Run(cellSet, 2); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - vtkm::cont::ArrayHandle cellFieldArray = maskCells.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 8), "Wrong result for Mask"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 8 && - cellFieldArray.ReadPortal().Get(7) == 14.f, - "Wrong cell field data"); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestUniform3D() const - { - std::cout << "Testing mask cells structured:" << std::endl; - - using CellSetType = vtkm::cont::CellSetStructured<3>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet1(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Output data set with cell set permuted - vtkm::worklet::Mask maskCells; - OutCellSetType outCellSet = maskCells.Run(cellSet, 9); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - vtkm::cont::ArrayHandle cellFieldArray = maskCells.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 7), "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 7 && - cellFieldArray.ReadPortal().Get(2) == 18.f, - "Wrong cell field data"); - } - - ///////////////////////////////////////////////////////////////////////////////////////////////// - void TestExplicit() const - { - std::cout << "Testing mask cells explicit:" << std::endl; - - using CellSetType = vtkm::cont::CellSetExplicit<>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - // Input data set created - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet5(); - CellSetType cellSet; - dataset.GetCellSet().AsCellSet(cellSet); - - // Output data set with cell set permuted - vtkm::worklet::Mask maskCells; - OutCellSetType outCellSet = maskCells.Run(cellSet, 2); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - vtkm::cont::ArrayHandle cellFieldArray = maskCells.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(test_equal(outCellSet.GetNumberOfCells(), 2), "Wrong result for ExtractCells"); - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 2 && - cellFieldArray.ReadPortal().Get(1) == 120.2f, - "Wrong cell field data"); - } - - void operator()() const - { - this->TestUniform2D(); - this->TestUniform3D(); - this->TestExplicit(); - } -}; - -int UnitTestMask(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestingMask(), argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestNDimsEntropy.cxx b/vtkm/worklet/testing/UnitTestNDimsEntropy.cxx deleted file mode 100644 index 4c5577bf9..000000000 --- a/vtkm/worklet/testing/UnitTestNDimsEntropy.cxx +++ /dev/null @@ -1,205 +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 - -namespace -{ -// Make testing dataset with three fields(variables), each one has 1000 values -vtkm::cont::DataSet MakeTestDataSet() -{ - vtkm::cont::DataSet dataSet; - - const int xVerts = 20; - const int yVerts = 50; - const int nVerts = xVerts * yVerts; - - vtkm::Float32 fieldA[nVerts] = { - 8, 10, 9, 8, 14, 11, 12, 9, 19, 7, 8, 11, 7, 10, 11, 11, 11, 6, 8, 8, 7, 15, 9, 7, - 8, 10, 9, 10, 10, 12, 7, 6, 14, 10, 14, 10, 7, 11, 13, 9, 13, 11, 10, 10, 12, 12, 7, 12, - 10, 11, 12, 8, 13, 9, 5, 12, 11, 9, 5, 9, 12, 9, 6, 10, 11, 9, 9, 11, 9, 7, 7, 18, - 16, 13, 12, 8, 10, 11, 9, 8, 17, 3, 15, 15, 9, 10, 10, 8, 10, 9, 7, 9, 8, 10, 13, 9, - 7, 11, 7, 10, 13, 10, 11, 9, 10, 7, 10, 6, 12, 6, 9, 7, 6, 12, 12, 9, 12, 12, 11, 6, - 1, 12, 8, 13, 14, 8, 8, 10, 7, 7, 6, 7, 5, 11, 6, 11, 13, 8, 13, 5, 9, 12, 7, 11, - 10, 15, 11, 9, 7, 12, 15, 7, 8, 7, 12, 8, 21, 16, 13, 11, 10, 14, 12, 11, 12, 14, 7, 11, - 7, 12, 16, 8, 10, 8, 9, 7, 8, 7, 13, 13, 11, 15, 7, 7, 6, 11, 7, 12, 12, 13, 14, 11, - 13, 11, 11, 9, 15, 8, 6, 11, 12, 10, 11, 7, 6, 14, 11, 10, 12, 5, 8, 9, 11, 15, 11, 10, - 17, 14, 9, 10, 10, 12, 11, 13, 13, 12, 11, 7, 8, 10, 7, 11, 10, 5, 8, 10, 13, 13, 12, 6, - 10, 7, 13, 8, 11, 7, 10, 7, 8, 7, 14, 16, 9, 11, 8, 11, 9, 15, 11, 10, 10, 12, 7, 7, - 11, 7, 5, 17, 9, 11, 11, 11, 10, 17, 10, 15, 7, 11, 12, 16, 9, 8, 11, 14, 9, 22, 8, 8, - 8, 13, 12, 12, 1, 14, 15, 6, 15, 8, 11, 16, 14, 8, 6, 9, 8, 9, 9, 10, 8, 6, 13, 8, - 6, 12, 11, 12, 13, 8, 6, 6, 5, 6, 10, 9, 11, 12, 14, 12, 10, 11, 10, 10, 8, 13, 8, 11, - 7, 13, 13, 12, 12, 13, 15, 4, 9, 16, 7, 9, 8, 10, 6, 9, 11, 12, 6, 7, 14, 6, 4, 15, - 5, 18, 9, 9, 11, 12, 9, 5, 6, 7, 15, 6, 11, 14, 8, 12, 6, 9, 5, 9, 14, 9, 12, 6, - 9, 14, 11, 12, 12, 13, 15, 9, 8, 7, 13, 12, 7, 13, 6, 9, 10, 10, 10, 9, 11, 5, 9, 13, - 16, 9, 10, 8, 9, 6, 13, 12, 8, 12, 9, 12, 17, 8, 11, 10, 8, 7, 11, 7, 13, 13, 10, 14, - 11, 9, 6, 6, 14, 16, 5, 9, 13, 11, 12, 7, 4, 6, 9, 11, 11, 10, 12, 9, 7, 13, 8, 8, - 12, 5, 10, 7, 11, 11, 10, 10, 14, 6, 8, 8, 3, 12, 16, 11, 11, 7, 6, 12, 11, 5, 9, 12, - 9, 13, 7, 8, 9, 9, 12, 7, 9, 8, 12, 11, 6, 10, 6, 7, 6, 11, 10, 8, 9, 8, 4, 19, - 12, 6, 10, 9, 6, 12, 9, 14, 7, 8, 11, 7, 7, 12, 13, 9, 13, 12, 8, 6, 10, 17, 19, 10, - 10, 13, 5, 11, 8, 10, 8, 16, 12, 6, 6, 7, 10, 9, 12, 8, 5, 10, 7, 18, 9, 12, 10, 4, - 9, 9, 15, 15, 6, 7, 7, 11, 12, 4, 8, 18, 5, 12, 12, 11, 10, 14, 9, 9, 10, 8, 10, 8, - 10, 9, 9, 4, 10, 12, 5, 13, 6, 9, 7, 5, 12, 8, 11, 10, 9, 17, 9, 9, 8, 11, 18, 11, - 10, 9, 4, 13, 10, 15, 5, 10, 9, 7, 7, 8, 10, 6, 6, 19, 10, 16, 7, 7, 9, 10, 10, 13, - 10, 10, 14, 13, 12, 8, 7, 13, 12, 11, 13, 12, 9, 8, 6, 8, 10, 3, 8, 8, 12, 12, 13, 13, - 10, 5, 10, 7, 13, 7, 9, 5, 13, 7, 10, 8, 13, 11, 17, 9, 6, 14, 10, 10, 13, 9, 15, 8, - 15, 9, 12, 11, 12, 8, 3, 9, 8, 10, 12, 8, 14, 13, 12, 11, 12, 9, 18, 10, 13, 7, 4, 4, - 11, 8, 3, 7, 9, 10, 12, 7, 11, 21, 9, 7, 8, 9, 10, 10, 11, 9, 15, 13, 21, 12, 8, 11, - 9, 10, 11, 9, 17, 8, 9, 8, 14, 6, 13, 9, 8, 11, 12, 12, 12, 11, 6, 13, 7, 9, 11, 15, - 17, 17, 11, 10, 7, 8, 11, 8, 6, 9, 13, 7, 9, 6, 5, 10, 7, 16, 16, 9, 7, 6, 14, 8, - 13, 16, 7, 7, 10, 11, 6, 10, 9, 9, 8, 14, 11, 9, 11, 9, 10, 11, 9, 8, 14, 11, 7, 12, - 11, 8, 9, 9, 10, 11, 11, 10, 9, 6, 6, 11, 16, 10, 7, 6, 6, 13, 18, 8, 12, 11, 14, 13, - 8, 8, 10, 17, 17, 6, 6, 10, 18, 5, 8, 11, 6, 6, 14, 10, 9, 6, 11, 6, 13, 12, 10, 6, - 9, 9, 9, 13, 7, 17, 10, 14, 10, 9, 10, 10, 11, 10, 11, 15, 13, 6, 12, 19, 10, 12, 12, 15, - 13, 10, 10, 13, 11, 13, 13, 17, 6, 5, 6, 7, 6, 9, 13, 11, 8, 12, 9, 6, 10, 16, 11, 12, - 5, 12, 14, 13, 13, 16, 11, 6, 12, 12, 15, 8, 7, 11, 8, 5, 10, 8, 9, 11, 9, 12, 10, 5, - 12, 11, 9, 6, 14, 12, 10, 11, 9, 6, 7, 12, 8, 12, 8, 15, 9, 8, 7, 9, 3, 6, 14, 7, - 8, 11, 9, 10, 12, 9, 10, 9, 8, 6, 12, 11, 6, 8, 9, 8, 15, 11, 7, 18, 12, 11, 10, 13, - 11, 11, 10, 7, 9, 8, 8, 11, 11, 13, 6, 12, 13, 16, 11, 11, 5, 12, 14, 15, 9, 14, 15, 6, - 8, 7, 6, 8, 9, 19, 7, 12, 11, 8, 14, 12, 10, 9, 3, 7 - }; - - vtkm::Float32 fieldB[nVerts] = { - 24, 19, 28, 19, 25, 28, 25, 22, 27, 26, 35, 26, 30, 28, 24, 23, 21, 31, 20, 11, 21, 22, 14, 25, - 20, 24, 24, 21, 24, 29, 26, 21, 32, 29, 23, 28, 31, 25, 23, 30, 18, 24, 22, 25, 33, 24, 22, 23, - 21, 17, 20, 28, 30, 18, 20, 32, 25, 24, 32, 15, 27, 24, 27, 19, 30, 27, 17, 24, 29, 23, 22, 19, - 24, 19, 28, 24, 25, 24, 25, 30, 24, 31, 30, 27, 25, 25, 25, 15, 29, 23, 29, 29, 21, 25, 35, 24, - 28, 10, 31, 23, 22, 22, 22, 33, 29, 27, 18, 27, 27, 24, 20, 20, 21, 29, 23, 31, 23, 23, 22, 23, - 30, 27, 28, 31, 16, 29, 25, 19, 33, 28, 25, 24, 15, 27, 37, 29, 15, 19, 14, 19, 24, 23, 30, 29, - 35, 22, 19, 26, 26, 14, 24, 30, 32, 23, 30, 29, 26, 27, 25, 23, 17, 26, 32, 29, 20, 17, 21, 23, - 22, 20, 36, 12, 26, 23, 15, 29, 24, 22, 26, 33, 24, 23, 20, 26, 22, 17, 26, 26, 34, 22, 26, 17, - 23, 18, 29, 27, 21, 29, 28, 29, 24, 25, 28, 19, 18, 21, 23, 23, 27, 25, 24, 25, 24, 25, 21, 25, - 21, 27, 23, 20, 29, 15, 28, 30, 24, 27, 17, 23, 16, 21, 25, 17, 27, 28, 21, 13, 19, 27, 16, 30, - 31, 25, 30, 17, 17, 25, 26, 22, 21, 17, 24, 17, 25, 22, 27, 14, 27, 24, 27, 25, 26, 31, 21, 23, - 30, 30, 22, 19, 23, 22, 23, 25, 24, 25, 24, 28, 26, 30, 18, 25, 30, 37, 27, 34, 28, 34, 25, 10, - 25, 22, 35, 30, 24, 32, 24, 34, 19, 29, 26, 16, 27, 17, 26, 23, 27, 25, 26, 21, 31, 21, 28, 15, - 32, 24, 23, 23, 18, 15, 22, 25, 16, 25, 31, 26, 25, 28, 24, 26, 23, 25, 33, 20, 27, 28, 24, 29, - 32, 20, 24, 20, 19, 32, 24, 6, 24, 21, 26, 18, 15, 30, 19, 26, 22, 30, 35, 23, 22, 30, 20, 22, - 18, 30, 28, 25, 16, 25, 27, 30, 18, 24, 30, 28, 20, 19, 20, 28, 21, 24, 15, 33, 20, 18, 20, 36, - 30, 26, 25, 18, 28, 27, 31, 31, 15, 26, 16, 22, 27, 14, 17, 27, 27, 22, 32, 30, 22, 34, 22, 25, - 20, 22, 26, 29, 28, 33, 18, 23, 20, 20, 27, 24, 28, 21, 25, 27, 25, 19, 19, 25, 19, 32, 29, 27, - 23, 21, 28, 33, 23, 23, 28, 26, 31, 19, 21, 29, 21, 27, 23, 32, 24, 26, 21, 28, 28, 24, 17, 31, - 27, 21, 19, 32, 28, 23, 30, 23, 29, 15, 26, 26, 15, 20, 25, 26, 27, 31, 21, 23, 23, 33, 28, 19, - 23, 22, 22, 25, 27, 17, 23, 17, 25, 28, 26, 30, 32, 31, 19, 25, 25, 19, 23, 29, 27, 23, 34, 22, - 13, 21, 32, 10, 20, 33, 21, 17, 29, 31, 14, 24, 23, 19, 19, 22, 17, 26, 37, 26, 22, 26, 38, 29, - 29, 27, 30, 20, 31, 14, 32, 32, 24, 23, 23, 18, 21, 31, 24, 20, 28, 15, 21, 25, 25, 20, 30, 25, - 22, 21, 21, 25, 24, 25, 18, 23, 28, 30, 20, 27, 27, 19, 10, 32, 24, 20, 29, 26, 25, 20, 25, 29, - 28, 24, 32, 26, 22, 19, 23, 27, 27, 29, 20, 25, 21, 30, 28, 31, 24, 19, 23, 19, 19, 18, 30, 18, - 16, 24, 20, 20, 30, 25, 29, 25, 31, 21, 28, 31, 24, 26, 27, 21, 24, 23, 26, 18, 32, 26, 28, 26, - 24, 26, 29, 30, 22, 20, 24, 28, 25, 29, 20, 21, 22, 15, 30, 27, 33, 26, 22, 32, 30, 31, 20, 19, - 24, 26, 27, 31, 17, 17, 33, 27, 16, 27, 27, 22, 27, 19, 24, 21, 17, 24, 28, 23, 26, 24, 19, 26, - 20, 24, 22, 19, 22, 21, 21, 28, 29, 39, 19, 16, 25, 29, 31, 22, 22, 29, 26, 22, 22, 22, 26, 23, - 23, 23, 30, 25, 25, 25, 27, 29, 18, 33, 21, 12, 22, 29, 12, 20, 35, 22, 34, 28, 18, 29, 21, 20, - 24, 33, 24, 26, 23, 34, 31, 25, 31, 22, 35, 21, 20, 29, 27, 22, 30, 22, 27, 23, 22, 32, 16, 19, - 27, 22, 24, 27, 21, 33, 25, 25, 19, 28, 20, 27, 21, 25, 28, 20, 27, 22, 21, 20, 26, 30, 33, 23, - 20, 24, 17, 23, 28, 35, 14, 23, 22, 28, 28, 26, 25, 18, 20, 28, 28, 22, 13, 24, 22, 20, 30, 26, - 26, 18, 22, 20, 23, 24, 20, 27, 34, 28, 18, 24, 34, 33, 25, 33, 37, 21, 20, 31, 19, 23, 29, 22, - 21, 24, 19, 27, 19, 32, 25, 23, 33, 26, 33, 27, 29, 30, 19, 22, 30, 19, 18, 24, 25, 17, 31, 19, - 31, 26, 22, 23, 28, 28, 25, 24, 19, 19, 27, 28, 23, 21, 29, 26, 31, 22, 22, 25, 16, 29, 21, 22, - 23, 25, 22, 21, 22, 19, 27, 26, 28, 30, 22, 21, 24, 22, 23, 26, 28, 22, 18, 25, 23, 27, 31, 19, - 15, 29, 20, 19, 27, 25, 21, 29, 22, 24, 25, 17, 36, 29, 22, 22, 24, 28, 27, 22, 26, 31, 29, 31, - 18, 25, 23, 16, 37, 27, 21, 31, 25, 24, 20, 23, 28, 33, 24, 21, 26, 20, 18, 31, 20, 24, 23, 19, - 27, 17, 23, 23, 20, 26, 28, 23, 26, 31, 25, 31, 19, 32, 26, 18, 19, 29, 20, 21, 15, 25, 27, 29, - 22, 22, 22, 26, 23, 22, 23, 29, 28, 20, 21, 22, 20, 22, 27, 25, 23, 32, 23, 20, 31, 20, 27, 26, - 34, 20, 22, 36, 21, 29, 25, 20, 21, 22, 29, 29, 25, 22, 24, 22 - }; - - vtkm::Float32 fieldC[nVerts] = { - 3, 1, 4, 6, 5, 4, 8, 7, 2, 9, 2, 0, 0, 4, 3, 2, 5, 2, 3, 6, 3, 8, 3, 4, - 3, 3, 2, 7, 2, 10, 9, 6, 1, 1, 4, 7, 3, 3, 1, 4, 4, 3, 9, 4, 4, 7, 3, 2, - 4, 7, 3, 3, 2, 10, 1, 6, 2, 2, 3, 8, 3, 3, 6, 9, 4, 1, 4, 3, 16, 7, 0, 1, - 8, 7, 13, 3, 5, 0, 3, 8, 10, 3, 5, 5, 1, 5, 2, 1, 3, 2, 5, 3, 4, 3, 3, 3, - 3, 1, 13, 2, 3, 1, 2, 7, 3, 4, 1, 2, 5, 4, 4, 4, 2, 6, 3, 2, 7, 8, 1, 3, - 4, 1, 2, 0, 1, 6, 1, 8, 8, 1, 1, 4, 2, 1, 4, 3, 5, 4, 6, 4, 2, 3, 8, 8, - 3, 3, 3, 4, 5, 8, 8, 16, 7, 12, 4, 3, 14, 8, 3, 12, 5, 0, 5, 3, 5, 2, 9, 2, - 9, 4, 1, 0, 0, 4, 4, 6, 3, 4, 11, 2, 4, 7, 4, 2, 1, 9, 4, 3, 2, 5, 1, 5, - 3, 8, 2, 8, 1, 8, 0, 4, 1, 3, 2, 1, 2, 3, 2, 1, 8, 5, 4, 1, 9, 9, 1, 3, - 5, 0, 1, 6, 10, 8, 3, 12, 3, 4, 4, 7, 1, 3, 6, 4, 4, 6, 1, 4, 7, 5, 6, 11, - 6, 5, 2, 7, 2, 5, 3, 5, 6, 3, 6, 2, 1, 10, 8, 3, 7, 0, 2, 6, 9, 3, 11, 3, - 2, 5, 1, 4, 6, 10, 9, 1, 4, 3, 7, 12, 3, 10, 0, 2, 11, 2, 1, 0, 4, 1, 2, 16, - 5, 17, 7, 8, 2, 10, 10, 3, 1, 3, 2, 2, 4, 8, 4, 3, 2, 4, 4, 6, 8, 6, 2, 3, - 2, 4, 2, 4, 7, 10, 5, 3, 5, 2, 4, 6, 9, 3, 1, 1, 1, 1, 4, 2, 2, 7, 4, 9, - 2, 3, 5, 6, 2, 5, 1, 6, 5, 7, 8, 3, 7, 2, 2, 8, 6, 2, 10, 2, 1, 4, 5, 1, - 1, 1, 5, 6, 1, 1, 4, 5, 4, 2, 4, 3, 2, 7, 19, 4, 7, 2, 7, 5, 2, 5, 3, 8, - 4, 6, 7, 2, 0, 0, 2, 12, 6, 2, 2, 3, 5, 9, 4, 9, 2, 2, 7, 8, 3, 3, 10, 6, - 3, 2, 1, 6, 2, 4, 6, 3, 5, 8, 2, 3, 6, 14, 0, 3, 6, 5, 2, 7, 0, 3, 8, 5, - 3, 2, 2, 5, 1, 3, 12, 11, 16, 2, 1, 3, 7, 3, 1, 6, 4, 3, 12, 5, 1, 3, 1, 4, - 9, 1, 3, 3, 4, 4, 6, 7, 7, 5, 2, 4, 2, 3, 2, 2, 6, 4, 2, 2, 3, 5, 1, 4, - 9, 1, 0, 7, 6, 4, 3, 3, 7, 3, 3, 6, 2, 7, 9, 3, 1, 16, 5, 4, 3, 6, 3, 2, - 5, 2, 2, 4, 3, 1, 3, 3, 6, 3, 5, 9, 1, 10, 1, 7, 2, 2, 6, 7, 3, 5, 3, 7, - 2, 2, 2, 2, 6, 4, 3, 2, 5, 5, 3, 15, 4, 2, 7, 7, 4, 3, 3, 5, 1, 2, 9, 0, - 5, 7, 12, 2, 4, 8, 5, 7, 8, 3, 2, 2, 18, 1, 7, 2, 2, 1, 3, 3, 3, 7, 1, 9, - 8, 4, 3, 7, 6, 4, 5, 2, 0, 5, 1, 5, 10, 4, 2, 8, 2, 2, 0, 5, 6, 4, 5, 0, - 1, 5, 11, 3, 3, 4, 4, 2, 3, 5, 1, 6, 5, 7, 2, 2, 5, 7, 4, 8, 4, 1, 1, 7, - 2, 3, 9, 6, 13, 1, 5, 4, 6, 2, 4, 11, 2, 5, 5, 1, 4, 1, 4, 7, 1, 5, 8, 3, - 1, 10, 9, 13, 1, 7, 2, 9, 4, 3, 3, 10, 12, 2, 0, 4, 6, 5, 5, 1, 4, 7, 2, 12, - 7, 6, 5, 0, 6, 4, 4, 12, 1, 3, 10, 1, 9, 2, 2, 2, 1, 5, 5, 6, 9, 6, 4, 1, - 11, 6, 9, 3, 2, 7, 1, 7, 4, 3, 0, 3, 1, 12, 17, 2, 1, 6, 4, 4, 2, 1, 5, 5, - 3, 2, 2, 4, 6, 5, 4, 6, 11, 3, 12, 6, 3, 6, 3, 0, 6, 3, 7, 4, 8, 5, 14, 5, - 1, 9, 4, 6, 5, 3, 9, 3, 1, 1, 0, 3, 7, 3, 5, 1, 6, 2, 2, 6, 2, 12, 1, 0, - 6, 3, 3, 5, 4, 7, 2, 2, 15, 7, 3, 10, 4, 2, 6, 3, 4, 8, 3, 1, 5, 5, 5, 4, - 3, 7, 3, 4, 5, 5, 2, 4, 2, 5, 1, 12, 5, 6, 3, 2, 8, 5, 2, 3, 11, 11, 6, 5, - 0, 3, 3, 9, 4, 2, 11, 1, 5, 3, 5, 6, 3, 6, 4, 2, 4, 10, 11, 3, 3, 4, 1, 1, - 1, 3, 5, 5, 1, 1, 4, 1, 5, 1, 6, 8, 6, 4, 6, 7, 6, 3, 5, 3, 6, 6, 6, 4, - 0, 6, 3, 1, 2, 4, 2, 6, 1, 1, 1, 2, 2, 4, 7, 2, 6, 2, 5, 7, 6, 4, 6, 3, - 1, 4, 5, 1, 4, 6, 2, 3, 0, 6, 11, 2, 9, 2, 6, 4, 5, 6, 2, 19, 2, 10, 4, 2, - 3, 3, 11, 7, 3, 3, 1, 5, 3, 6, 4, 3, 0, 6, 6, 6, 4, 2, 5, 2, 2, 2, 6, 10, - 4, 9, 3, 7, 7, 0, 6, 8, 5, 2, 3, 2, 3, 3, 3, 1, 6, 1, 8, 2, 5, 3, 6, 11, - 5, 7, 2, 6, 7, 3, 4, 1, 0, 5, 8, 3, 2, 9, 3, 1, 2, 3, 3, 9, 5, 6, 5, 1, - 4, 5, 6, 7, 6, 1, 5, 1, 6, 6, 2, 6, 7, 2, 4, 6 - }; - - vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vtkm::Id3(xVerts, yVerts, 1)); - dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates)); - - // Set point scalars - dataSet.AddField(vtkm::cont::make_Field( - "fieldA", vtkm::cont::Field::Association::POINTS, fieldA, nVerts, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "fieldB", vtkm::cont::Field::Association::POINTS, fieldB, nVerts, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "fieldC", vtkm::cont::Field::Association::POINTS, fieldC, nVerts, vtkm::CopyFlag::On)); - - return dataSet; -} - -// -// Create a dataset with known point data -// Extract the three field -// Run NDimsEntropy to calculate the entropy -// -void TestNDimsEntropy() -{ - // Data attached is the poisson distribution - vtkm::cont::DataSet ds = MakeTestDataSet(); - - vtkm::worklet::NDimsEntropy ndEntropy; - ndEntropy.SetNumOfDataPoints(ds.GetField(0).GetNumberOfValues()); - - // Add field one by one - ndEntropy.AddField(ds.GetField("fieldA").GetData(), 10); - ndEntropy.AddField(ds.GetField("fieldB").GetData(), 10); - ndEntropy.AddField(ds.GetField("fieldC").GetData(), 10); - - // Run worklet to calculate multi-variate entropy - vtkm::Float64 entropy = ndEntropy.Run(); - - VTKM_TEST_ASSERT(fabs(entropy - 7.457857) < 0.001, - "N-Dimentional entropy calculation is incorrect"); -} // TestNDimsEntropy -} - -int UnitTestNDimsEntropy(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestNDimsEntropy, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestNDimsHistMarginalization.cxx b/vtkm/worklet/testing/UnitTestNDimsHistMarginalization.cxx index deb870b22..699e7ca86 100644 --- a/vtkm/worklet/testing/UnitTestNDimsHistMarginalization.cxx +++ b/vtkm/worklet/testing/UnitTestNDimsHistMarginalization.cxx @@ -8,8 +8,8 @@ // PURPOSE. See the above copyright notice for more information. //============================================================================ +#include #include -#include #include #include diff --git a/vtkm/worklet/testing/UnitTestNDimsHistogram.cxx b/vtkm/worklet/testing/UnitTestNDimsHistogram.cxx deleted file mode 100644 index 02d8493f7..000000000 --- a/vtkm/worklet/testing/UnitTestNDimsHistogram.cxx +++ /dev/null @@ -1,121 +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 - -namespace -{ -// Make testing dataset with three fields(variables), each one has 100 values -vtkm::cont::DataSet MakeTestDataSet() -{ - vtkm::cont::DataSet dataSet; - - const int nVerts = 100; - - vtkm::Float32 fieldA[nVerts] = { 8, 10, 9, 8, 14, 11, 12, 9, 19, 7, 8, 11, 7, 10, 11, - 11, 11, 6, 8, 8, 7, 15, 9, 7, 8, 10, 9, 10, 10, 12, - 7, 6, 14, 10, 14, 10, 7, 11, 13, 9, 13, 11, 10, 10, 12, - 12, 7, 12, 10, 11, 12, 8, 13, 9, 5, 12, 11, 9, 5, 9, - 12, 9, 6, 10, 11, 9, 9, 11, 9, 7, 7, 18, 16, 13, 12, - 8, 10, 11, 9, 8, 17, 3, 15, 15, 9, 10, 10, 8, 10, 9, - 7, 9, 8, 10, 13, 9, 7, 11, 7, 10 }; - - vtkm::Float32 fieldB[nVerts] = { 24, 19, 28, 19, 25, 28, 25, 22, 27, 26, 35, 26, 30, 28, 24, - 23, 21, 31, 20, 11, 21, 22, 14, 25, 20, 24, 24, 21, 24, 29, - 26, 21, 32, 29, 23, 28, 31, 25, 23, 30, 18, 24, 22, 25, 33, - 24, 22, 23, 21, 17, 20, 28, 30, 18, 20, 32, 25, 24, 32, 15, - 27, 24, 27, 19, 30, 27, 17, 24, 29, 23, 22, 19, 24, 19, 28, - 24, 25, 24, 25, 30, 24, 31, 30, 27, 25, 25, 25, 15, 29, 23, - 29, 29, 21, 25, 35, 24, 28, 10, 31, 23 }; - - vtkm::Float32 fieldC[nVerts] = { - 3, 1, 4, 6, 5, 4, 8, 7, 2, 9, 2, 0, 0, 4, 3, 2, 5, 2, 3, 6, 3, 8, 3, 4, 3, - 3, 2, 7, 2, 10, 9, 6, 1, 1, 4, 7, 3, 3, 1, 4, 4, 3, 9, 4, 4, 7, 3, 2, 4, 7, - 3, 3, 2, 10, 1, 6, 2, 2, 3, 8, 3, 3, 6, 9, 4, 1, 4, 3, 16, 7, 0, 1, 8, 7, 13, - 3, 5, 0, 3, 8, 10, 3, 5, 5, 1, 5, 2, 1, 3, 2, 5, 3, 4, 3, 3, 3, 3, 1, 13, 2 - }; - - // Set point scalars - dataSet.AddField(vtkm::cont::make_Field( - "fieldA", vtkm::cont::Field::Association::POINTS, fieldA, nVerts, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "fieldB", vtkm::cont::Field::Association::POINTS, fieldB, nVerts, vtkm::CopyFlag::On)); - dataSet.AddField(vtkm::cont::make_Field( - "fieldC", vtkm::cont::Field::Association::POINTS, fieldC, nVerts, vtkm::CopyFlag::On)); - - return dataSet; -} - -void TestNDimsHistogram() -{ - // Create a dataset - vtkm::cont::DataSet ds = MakeTestDataSet(); - - vtkm::worklet::NDimsHistogram ndHistogram; - - // Set the number of data points - ndHistogram.SetNumOfDataPoints(ds.GetField(0).GetNumberOfValues()); - - // Add field one by one - vtkm::Range rangeFieldA; - vtkm::Float64 deltaFieldA; - ndHistogram.AddField(ds.GetField("fieldA").GetData(), 4, rangeFieldA, deltaFieldA); - - vtkm::Range rangeFieldB; - vtkm::Float64 deltaFieldB; - ndHistogram.AddField(ds.GetField("fieldB").GetData(), 4, rangeFieldB, deltaFieldB); - - vtkm::Range rangeFieldC; - vtkm::Float64 deltaFieldC; - ndHistogram.AddField(ds.GetField("fieldC").GetData(), 4, rangeFieldC, deltaFieldC); - - // the return binIds and freqs is sparse distribution representation - // (we do not keep the 0 frequency entities) - // e.g. we have three variable(data arrays) in this example - // binIds[0, 1, 2][j] is a combination of bin ID of three variable, - // freqs[j] is the frequency of this bin IDs combination - std::vector> binIds; - vtkm::cont::ArrayHandle freqs; - ndHistogram.Run(binIds, freqs); - - // Ground truth ND histogram - vtkm::Id gtNonSparseBins = 33; - vtkm::Id gtIdx0[33] = { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3 }; - vtkm::Id gtIdx1[33] = { 1, 1, 2, 3, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, - 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 1, 1, 2, 2, 2, 3 }; - vtkm::Id gtIdx2[33] = { 0, 1, 1, 0, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 3, - 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 0, 2, 0, 1, 2, 1 }; - vtkm::Id gtFreq[33] = { 1, 1, 1, 3, 2, 1, 1, 6, 6, 3, 17, 8, 2, 6, 2, 1, 2, - 1, 1, 4, 11, 4, 1, 1, 3, 3, 1, 1, 1, 1, 1, 2, 1 }; - - // Check result - vtkm::Id nonSparseBins = binIds[0].WritePortal().GetNumberOfValues(); - VTKM_TEST_ASSERT(nonSparseBins == gtNonSparseBins, "Incorrect ND-histogram results"); - - for (int i = 0; i < nonSparseBins; i++) - { - vtkm::Id idx0 = binIds[0].WritePortal().Get(i); - vtkm::Id idx1 = binIds[1].WritePortal().Get(i); - vtkm::Id idx2 = binIds[2].WritePortal().Get(i); - vtkm::Id f = freqs.WritePortal().Get(i); - VTKM_TEST_ASSERT(idx0 == gtIdx0[i] && idx1 == gtIdx1[i] && idx2 == gtIdx2[i] && f == gtFreq[i], - "Incorrect ND-histogram results"); - } -} // TestNDHistogram -} - -int UnitTestNDimsHistogram(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestNDimsHistogram, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestPointerJumping.cxx b/vtkm/worklet/testing/UnitTestPointerJumping.cxx deleted file mode 100644 index 07d481055..000000000 --- a/vtkm/worklet/testing/UnitTestPointerJumping.cxx +++ /dev/null @@ -1,40 +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 - -void TestLinear() -{ - const vtkm::Id N = 100; - auto counting = vtkm::cont::make_ArrayHandleCounting(-1, 1, N - 1); - - vtkm::cont::ArrayHandle parents; - vtkm::cont::ArrayCopy(counting, parents); - parents.WritePortal().Set(0, 0); - - vtkm::cont::Invoker invoker; - invoker(vtkm::worklet::connectivity::PointerJumping{}, parents); - VTKM_TEST_ASSERT( - test_equal_ArrayHandles(vtkm::cont::ArrayHandleConstant(0, N - 1), parents)); -} - -void TestPointerJumping() -{ - TestLinear(); -} - -int UnitTestPointerJumping(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestPointerJumping, argc, argv); -} diff --git a/vtkm/worklet/testing/UnitTestThreshold.cxx b/vtkm/worklet/testing/UnitTestThreshold.cxx deleted file mode 100644 index e8f3e34f1..000000000 --- a/vtkm/worklet/testing/UnitTestThreshold.cxx +++ /dev/null @@ -1,252 +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 -#include -#include -#include -#include - -namespace -{ - -class HasValue -{ -public: - VTKM_CONT - HasValue(vtkm::Float32 value) - : Value(value) - { - } - - template - VTKM_EXEC bool operator()(ScalarType value) const - { - return static_cast(value) == this->Value; - } - -private: - vtkm::Float32 Value; -}; - -class ThresholdRange -{ -public: - VTKM_CONT - ThresholdRange() {} - - ThresholdRange(const vtkm::Float64& lower, const vtkm::Float64& upper) - : Lower(lower) - , Upper(upper) - { - } - - void SetLowerValue(const vtkm::Float64& lower) { Lower = lower; } - void SetUpperValue(const vtkm::Float64& upper) { Upper = upper; } - - template - VTKM_EXEC bool operator()(const T& value) const - { - - return value >= static_cast(this->Lower) && value <= static_cast(this->Upper); - } - - //Needed to work with ArrayHandleVirtual - template - VTKM_EXEC bool operator()( - const vtkm::internal::ArrayPortalValueReference& value) const - { - using T = typename PortalType::ValueType; - return value.Get() >= static_cast(this->Lower) && value.Get() <= static_cast(this->Upper); - } - -private: - vtkm::Float64 Lower; - vtkm::Float64 Upper; -}; - -using vtkm::cont::testing::MakeTestDataSet; - -class TestingThreshold -{ -public: - void TestUniform2D(bool returnAllInRange) const - { - using CellSetType = vtkm::cont::CellSetStructured<2>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - vtkm::cont::DataSet dataset = MakeTestDataSet().Make2DUniformDataSet0(); - - CellSetType cellset; - dataset.GetCellSet().AsCellSet(cellset); - - vtkm::cont::ArrayHandle pointvar; - dataset.GetField("pointvar").GetData().AsArrayHandle(pointvar); - - vtkm::worklet::Threshold threshold; - ThresholdRange predicate; - - if (returnAllInRange) - { - std::cout << "Testing threshold on 2D uniform dataset returning values 'all in range'" - << std::endl; - predicate.SetLowerValue(10); - predicate.SetUpperValue(60); - } - else - { - std::cout << "Testing threshold on 2D uniform dataset returning values 'part in range'" - << std::endl; - predicate.SetLowerValue(60); - predicate.SetUpperValue(61); - } - - OutCellSetType outCellSet = threshold.Run( - cellset, pointvar, vtkm::cont::Field::Association::POINTS, predicate, returnAllInRange); - - if (returnAllInRange) - { - VTKM_TEST_ASSERT(outCellSet.GetNumberOfCells() == 1, "Wrong number of cells"); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - vtkm::cont::ArrayHandle cellFieldArray = threshold.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 1 && - cellFieldArray.ReadPortal().Get(0) == 100.1f, - "Wrong cell field data"); - } - else - { - VTKM_TEST_ASSERT(outCellSet.GetNumberOfCells() == 1, "Wrong number of cells"); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - vtkm::cont::ArrayHandle cellFieldArray = threshold.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 1 && - cellFieldArray.ReadPortal().Get(0) == 200.1f, - "Wrong cell field data"); - } - } - - void TestUniform3D(bool returnAllInRange) const - { - using CellSetType = vtkm::cont::CellSetStructured<3>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DUniformDataSet0(); - - CellSetType cellset; - dataset.GetCellSet().AsCellSet(cellset); - - vtkm::cont::ArrayHandle pointvar; - dataset.GetField("pointvar").GetData().AsArrayHandle(pointvar); - - vtkm::worklet::Threshold threshold; - ThresholdRange predicate; - - if (returnAllInRange) - { - std::cout << "Testing threshold on 3D uniform dataset returning values 'all in range'" - << std::endl; - predicate.SetLowerValue(10.1); - predicate.SetUpperValue(180); - } - else - { - std::cout << "Testing threshold on 3D uniform dataset returning values 'part in range'" - << std::endl; - predicate.SetLowerValue(20); - predicate.SetUpperValue(21); - } - - OutCellSetType outCellSet = threshold.Run( - cellset, pointvar, vtkm::cont::Field::Association::POINTS, predicate, returnAllInRange); - - if (returnAllInRange) - { - VTKM_TEST_ASSERT(outCellSet.GetNumberOfCells() == 3, "Wrong number of cells"); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - vtkm::cont::ArrayHandle cellFieldArray = threshold.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 3 && - cellFieldArray.ReadPortal().Get(0) == 100.1f && - cellFieldArray.ReadPortal().Get(1) == 100.2f && - cellFieldArray.ReadPortal().Get(2) == 100.3f, - "Wrong cell field data"); - } - else - { - VTKM_TEST_ASSERT(outCellSet.GetNumberOfCells() == 2, "Wrong number of cells"); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - vtkm::cont::ArrayHandle cellFieldArray = threshold.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 2 && - cellFieldArray.ReadPortal().Get(0) == 100.1f && - cellFieldArray.ReadPortal().Get(1) == 100.2f, - "Wrong cell field data"); - } - } - - void TestExplicit3D() const - { - std::cout << "Testing threshold on 3D explicit dataset" << std::endl; - - using CellSetType = vtkm::cont::CellSetExplicit<>; - using OutCellSetType = vtkm::cont::CellSetPermutation; - - vtkm::cont::DataSet dataset = MakeTestDataSet().Make3DExplicitDataSet0(); - - CellSetType cellset; - dataset.GetCellSet().AsCellSet(cellset); - - vtkm::cont::ArrayHandle cellvar; - dataset.GetField("cellvar").GetData().AsArrayHandle(cellvar); - - vtkm::worklet::Threshold threshold; - OutCellSetType outCellSet = - threshold.Run(cellset, cellvar, vtkm::cont::Field::Association::CELL_SET, HasValue(100.1f)); - - VTKM_TEST_ASSERT(outCellSet.GetNumberOfCells() == 1, "Wrong number of cells"); - - vtkm::cont::ArrayHandle cellFieldArray = threshold.ProcessCellField(cellvar); - - VTKM_TEST_ASSERT(cellFieldArray.GetNumberOfValues() == 1 && - cellFieldArray.ReadPortal().Get(0) == 100.1f, - "Wrong cell field data"); - } - - void operator()() const - { - this->TestUniform2D(false); - this->TestUniform2D(true); - this->TestUniform3D(false); - this->TestUniform3D(true); - this->TestExplicit3D(); - } -}; -} - -int UnitTestThreshold(int argc, char* argv[]) -{ - return vtkm::cont::testing::Testing::Run(TestingThreshold(), argc, argv); -}