Merge branch 'master' into new_contour

This commit is contained in:
Li-Ta Lo 2022-01-26 11:54:06 -07:00
commit 175f9010a5
183 changed files with 3846 additions and 5822 deletions

@ -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

@ -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()

@ -33,7 +33,6 @@
#include <vtkm/filter/PointAverage.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/Tetrahedralize.h>
#include <vtkm/filter/Threshold.h>
#include <vtkm/filter/Triangulate.h>
#include <vtkm/filter/VectorMagnitude.h>
#include <vtkm/filter/VertexClustering.h>
@ -41,6 +40,7 @@
#include <vtkm/filter/WarpVector.h>
#include <vtkm/filter/contour/Contour.h>
#include <vtkm/filter/entity_extraction/ExternalFaces.h>
#include <vtkm/filter/entity_extraction/Threshold.h>
#include <vtkm/filter/entity_extraction/ThresholdPoints.h>
#include <vtkm/io/VTKDataSetReader.h>
@ -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);

@ -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.

@ -8,7 +8,7 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/worklet/FieldHistogram.h>
#include <vtkm/filter/density_estimate/worklet/FieldHistogram.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayPortalToIterators.h>

@ -9,178 +9,43 @@
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/DeviceAdapterList.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/internal/ArrayCopyUnknown.h>
#include <vtkm/worklet/WorkletMapField.h>
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 <typename InType, typename OutType>
VTKM_EXEC void operator()(const InType& in, OutType& out) const
{
out = in;
}
};
struct UnknownCopyOnDevice
{
bool Called = false;
template <typename InType, typename OutType>
void operator()(vtkm::cont::DeviceAdapterId device,
const vtkm::cont::ArrayHandleRecombineVec<InType>& in,
const vtkm::cont::ArrayHandleRecombineVec<OutType>& 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 <typename OutType, typename InType>
void operator()(const vtkm::cont::ArrayHandleRecombineVec<OutType>& out,
const vtkm::cont::ArrayHandleRecombineVec<InType>& 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 <typename InType>
void operator()(const vtkm::cont::ArrayHandleRecombineVec<InType>& in,
const vtkm::cont::UnknownArrayHandle& out) const
{
out.Allocate(in.GetNumberOfValues());
this->DoIt(in, out, typename std::is_same<vtkm::FloatDefault, InType>::type{});
}
template <typename InType>
void DoIt(const vtkm::cont::ArrayHandleRecombineVec<InType>& in,
const vtkm::cont::UnknownArrayHandle& out,
std::false_type) const
{
// Source is not float.
if (out.IsBaseComponentType<InType>())
{
// Arrays have the same base component type. Copy directly.
UnknownCopyFunctor2{}(out.ExtractArrayFromComponents<InType>(), in);
}
else if (out.IsBaseComponentType<vtkm::FloatDefault>())
{
// Can copy anything to default float.
UnknownCopyFunctor2{}(out.ExtractArrayFromComponents<vtkm::FloatDefault>(), 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 <typename InType>
void DoIt(const vtkm::cont::ArrayHandleRecombineVec<InType>& 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 <vtkm/cont/ArrayCopyDevice.h>
namespace vtkm
{
namespace cont
{
void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source,
vtkm::cont::UnknownArrayHandle& destination)
namespace detail
{
if (!destination.IsValid())
void ArrayCopyConcreteSrc<vtkm::cont::StorageTagCounting>::CopyCountingFloat(
vtkm::FloatDefault start,
vtkm::FloatDefault step,
vtkm::Id size,
const vtkm::cont::UnknownArrayHandle& result) const
{
if (result.IsBaseComponentType<vtkm::FloatDefault>())
{
destination = source.NewInstanceBasic();
auto outArray = result.ExtractComponent<vtkm::FloatDefault>(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<vtkm::FloatDefault> outArray;
outArray.Allocate(size);
CopyCountingFloat(start, step, size, outArray);
result.DeepCopyFrom(outArray);
}
DoUnknownArrayCopy(source, destination);
}
namespace internal
vtkm::cont::ArrayHandle<Id> ArrayCopyConcreteSrc<vtkm::cont::StorageTagCounting>::CopyCountingId(
const vtkm::cont::ArrayHandleCounting<vtkm::Id>& source) const
{
void ArrayCopyUnknown(const vtkm::cont::UnknownArrayHandle& source,
vtkm::cont::UnknownArrayHandle& destination)
{
vtkm::cont::ArrayCopy(source, destination);
vtkm::cont::ArrayHandle<Id> 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

@ -10,19 +10,20 @@
#ifndef vtk_m_cont_ArrayCopy_h
#define vtk_m_cont_ArrayCopy_h
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapterTag.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/ArrayHandleConcatenate.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleView.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/internal/ArrayHandleDeprecated.h>
#include <vtkm/cont/vtkm_cont_export.h>
// 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 <vtkm/cont/internal/MapArrayPermutation.h>
#include <vtkm/StaticAssert.h>
#include <vtkm/VecTraits.h>
namespace vtkm
{
@ -32,72 +33,91 @@ namespace cont
namespace detail
{
// Element-wise copy.
template <typename InArrayType, typename OutArrayType>
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 <typename T>
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<T>::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 <typename InArrayType, typename OutArrayType>
void ArrayCopyOldImpl(const InArrayType& in, OutArrayType& out, std::false_type /* Copy storage */)
{
ArrayCopyWithAlgorithm(in, out);
}
template <typename S>
struct ArrayCopyConcreteSrc;
// Copy storage for implicit arrays, must be of same type:
// TODO: This will go away once ArrayHandleNewStyle becomes ArrayHandle.
template <typename ArrayType>
void ArrayCopyOldImpl(const ArrayType& in, ArrayType& out, std::true_type /* Copy storage */)
template <typename SrcIsArrayHandle>
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 <typename InArrayType, typename OutArrayType>
VTKM_CONT void ArrayCopyImpl(const InArrayType& source,
OutArrayType& destination,
std::false_type /* New style */)
{
using SameTypes = std::is_same<InArrayType, OutArrayType>;
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<OutArrayType>;
using JustCopyStorage = std::integral_constant<bool, SameTypes::value && !IsWritable::value>;
ArrayCopyOldImpl(source, destination, JustCopyStorage{});
}
// TODO: ArrayHandleNewStyle will eventually become ArrayHandle, in which case this
// will become ArrayCopyWithAlgorithm
template <typename T1, typename S1, typename T2, typename S2>
VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T1, S1>& source,
vtkm::cont::ArrayHandle<T2, S2>& destination,
std::true_type /* New style */)
{
VTKM_STATIC_ASSERT((!std::is_same<T1, T2>::value || !std::is_same<S1, S2>::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 <typename T, typename S>
VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T, S>& source,
vtkm::cont::ArrayHandle<T, S>& destination,
std::true_type /* New style */)
template <typename SrcIsArrayHandle>
inline void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source,
const vtkm::cont::UnknownArrayHandle& destination,
SrcIsArrayHandle,
std::false_type)
{
destination.DeepCopyFrom(source);
}
} // namespace detail
template <typename T, typename S>
void ArrayCopyImpl(const vtkm::cont::UnknownArrayHandle& source,
vtkm::cont::ArrayHandle<T, S>& destination,
std::false_type,
std::true_type)
{
detail::ArrayCopyValueTypeCheck<T>();
using DestType = vtkm::cont::ArrayHandle<T, S>;
if (source.CanConvert<DestType>())
{
destination.DeepCopyFrom(source.AsArrayHandle<DestType>());
}
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 <typename TS, typename SS, typename TD, typename SD>
void ArrayCopyImpl(const vtkm::cont::ArrayHandle<TS, SS>& source,
vtkm::cont::ArrayHandle<TD, SD>& destination,
std::true_type,
std::true_type)
{
ArrayCopyValueTypeCheck<TS>();
ArrayCopyValueTypeCheck<TD>();
detail::ArrayCopyConcreteSrc<SS>{}(source, destination);
}
// Special case of copying data when type is the same.
template <typename T, typename S>
void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T, S>& source,
vtkm::cont::ArrayHandle<T, S>& 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<T, S>& 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 <typename InValueType, typename InStorage, typename OutValueType, typename OutStorage>
VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle<InValueType, InStorage>& source,
vtkm::cont::ArrayHandle<OutValueType, OutStorage>& destination)
template <typename SourceArrayType, typename DestArrayType>
inline void ArrayCopy(const SourceArrayType& source, DestArrayType& destination)
{
using InArrayType = vtkm::cont::ArrayHandle<InValueType, InStorage>;
using OutArrayType = vtkm::cont::ArrayHandle<OutValueType, OutStorage>;
using SameTypes = std::is_same<InArrayType, OutArrayType>;
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<OutArrayType>;
// 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<vtkm::cont::internal::ArrayHandleDeprecated<InValueType, InStorage>,
InArrayType>;
// Static dispatch cases 1 & 2
detail::ArrayCopyImpl(source, destination, std::integral_constant<bool, !IsOldStyle::value>{});
detail::ArrayCopyImpl(source,
destination,
typename internal::ArrayHandleCheck<SourceArrayType>::type{},
typename internal::ArrayHandleCheck<DestArrayType>::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 <typename T, typename S>
VTKM_CONT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source,
vtkm::cont::ArrayHandle<T, S>& destination)
// Special case where we allow a const UnknownArrayHandle as output.
template <typename SourceArrayType>
inline void ArrayCopy(const SourceArrayType& source, vtkm::cont::UnknownArrayHandle& destination)
{
using DestType = vtkm::cont::ArrayHandle<T, S>;
if (source.CanConvert<DestType>())
{
ArrayCopy(source.AsArrayHandle<DestType>(), 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<SourceArrayType>::type{},
std::false_type{});
}
// Invalid const ArrayHandle in destination, which is not allowed because it will
// not work in all cases.
template <typename T, typename S>
void ArrayCopy(const vtkm::cont::UnknownArrayHandle&, const vtkm::cont::ArrayHandle<T, S>&)
{
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 <typename S>
struct ArrayCopyConcreteSrc
{
template <typename T, typename DestArray>
void operator()(const vtkm::cont::ArrayHandle<T, S>& source, DestArray& destination) const
{
using ArrayType = vtkm::cont::ArrayHandle<T, S>;
this->DoIt(
source, destination, vtkm::cont::internal::ArrayExtractComponentIsInefficient<ArrayType>{});
}
template <typename T, typename DestArray>
void DoIt(const vtkm::cont::ArrayHandle<T, S>& source,
DestArray& destination,
std::false_type vtkmNotUsed(isInefficient)) const
{
vtkm::cont::ArrayCopy(vtkm::cont::UnknownArrayHandle{ source }, destination);
}
template <typename T, typename DestArray>
void DoIt(const vtkm::cont::ArrayHandle<T, S>& 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<vtkm::cont::ArrayHandle<T, S>>() +
" 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<vtkm::cont::StorageTagConstant>
{
template <typename T1, typename T2, typename S2>
void operator()(const vtkm::cont::ArrayHandle<T1, vtkm::cont::StorageTagConstant>& source_,
vtkm::cont::ArrayHandle<T2, S2>& destination) const
{
vtkm::cont::ArrayHandleConstant<T1> source = source_;
destination.AllocateAndFill(source.GetNumberOfValues(), static_cast<T2>(source.GetValue()));
}
};
// Special case for ArrayHandleIndex to be efficient.
template <>
struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagIndex>
{
template <typename T, typename S>
void operator()(const vtkm::cont::ArrayHandleIndex& source,
vtkm::cont::ArrayHandle<T, S>& 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<vtkm::cont::StorageTagCounting>
{
template <typename T1, typename T2, typename S2>
void operator()(const vtkm::cont::ArrayHandle<T1, vtkm::cont::StorageTagCounting>& source,
vtkm::cont::ArrayHandle<T2, S2>& destination) const
{
vtkm::cont::ArrayHandleCounting<T1> 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<T1>;
using VTraits2 = vtkm::VecTraits<T2>;
for (vtkm::IdComponent comp = 0; comp < VTraits1::GetNumberOfComponents(start); ++comp)
{
this->CopyCountingFloat(
static_cast<vtkm::FloatDefault>(VTraits1::GetComponent(start, comp)),
static_cast<vtkm::FloatDefault>(VTraits1::GetComponent(step, comp)),
size,
unknownDest.ExtractComponent<typename VTraits2::BaseComponentType>(comp));
}
}
void operator()(const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagCounting>& source,
vtkm::cont::ArrayHandle<vtkm::Id>& 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<Id> CopyCountingId(
const vtkm::cont::ArrayHandleCounting<vtkm::Id>& source) const;
};
// Special case for ArrayHandleConcatenate to be efficient
template <typename ST1, typename ST2>
struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagConcatenate<ST1, ST2>>
{
template <typename SourceArrayType, typename DestArrayType>
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 <typename SIndex, typename SValue>
struct ArrayCopyConcreteSrc<vtkm::cont::StorageTagPermutation<SIndex, SValue>>
{
using SourceStorageTag = vtkm::cont::StorageTagPermutation<SIndex, SValue>;
template <typename T1, typename T2, typename S2>
void operator()(const vtkm::cont::ArrayHandle<T1, SourceStorageTag>& source,
vtkm::cont::ArrayHandle<T2, S2>& 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

153
vtkm/cont/ArrayCopyDevice.h Normal file

@ -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 <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapterTag.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/internal/ArrayHandleDeprecated.h>
#include <vtkm/cont/vtkm_cont_export.h>
// 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 <typename InArrayType, typename OutArrayType>
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 <typename InArrayType, typename OutArrayType>
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 <typename ArrayType>
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 <typename InArrayType, typename OutArrayType>
VTKM_CONT void ArrayCopyImpl(const InArrayType& source,
OutArrayType& destination,
std::false_type /* New style */)
{
using SameTypes = std::is_same<InArrayType, OutArrayType>;
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<OutArrayType>;
using JustCopyStorage = std::integral_constant<bool, SameTypes::value && !IsWritable::value>;
ArrayCopyOldImpl(source, destination, JustCopyStorage{});
}
// TODO: ArrayHandleNewStyle will eventually become ArrayHandle, in which case this
// will become ArrayCopyWithAlgorithm
template <typename T1, typename S1, typename T2, typename S2>
VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T1, S1>& source,
vtkm::cont::ArrayHandle<T2, S2>& destination,
std::true_type /* New style */)
{
VTKM_STATIC_ASSERT((!std::is_same<T1, T2>::value || !std::is_same<S1, S2>::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 <typename T, typename S>
VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T, S>& source,
vtkm::cont::ArrayHandle<T, S>& 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 <typename InValueType, typename InStorage, typename OutValueType, typename OutStorage>
VTKM_CONT void ArrayCopyDevice(const vtkm::cont::ArrayHandle<InValueType, InStorage>& source,
vtkm::cont::ArrayHandle<OutValueType, OutStorage>& destination)
{
using InArrayType = vtkm::cont::ArrayHandle<InValueType, InStorage>;
using OutArrayType = vtkm::cont::ArrayHandle<OutValueType, OutStorage>;
using SameTypes = std::is_same<InArrayType, OutArrayType>;
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<OutArrayType>;
// 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<vtkm::cont::internal::ArrayHandleDeprecated<InValueType, InStorage>,
InArrayType>;
// Static dispatch cases 1 & 2
detail::ArrayCopyImpl(source, destination, std::integral_constant<bool, !IsOldStyle::value>{});
}
/// @}
}
} // namespace vtkm::cont
#endif //vtk_m_cont_ArrayCopyDevice_h

@ -19,6 +19,8 @@
#include <vtkm/VecFlat.h>
#include <vtkm/VecTraits.h>
#include <vtkmstd/integer_sequence.h>
#include <vtkm/cont/vtkm_cont_export.h>
namespace vtkm
@ -137,6 +139,39 @@ struct ArrayExtractComponentImpl<vtkm::cont::StorageTagBasic>
}
};
namespace detail
{
template <std::size_t, typename Super>
struct ForwardSuper : Super
{
};
template <typename sequence, typename... Supers>
struct SharedSupersImpl;
template <std::size_t... Indices, typename... Supers>
struct SharedSupersImpl<vtkmstd::index_sequence<Indices...>, Supers...>
: ForwardSuper<Indices, Supers>...
{
};
} // 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 <typename... Supers>
using DuplicatedSuperclasses =
detail::SharedSupersImpl<vtkmstd::make_index_sequence<sizeof...(Supers)>, Supers...>;
template <typename... StorageTags>
using ArrayExtractComponentImplInherit =
DuplicatedSuperclasses<vtkm::cont::internal::ArrayExtractComponentImpl<StorageTags>...>;
/// \brief Resolves to true if ArrayHandleComponent of the array handle would be inefficient.
///
template <typename ArrayHandleType>

@ -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 <typename... STs>
struct ArrayExtractComponentImpl<vtkm::cont::StorageTagCartesianProduct<STs...>>
: vtkm::cont::internal::ArrayExtractComponentImplInherit<STs...>
{
template <typename T>
vtkm::cont::ArrayHandleStride<T> AdjustStrideForComponent(

@ -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 <typename... StorageTags>
struct ArrayExtractComponentImpl<StorageTagCompositeVec<StorageTags...>>
: vtkm::cont::internal::ArrayExtractComponentImplInherit<StorageTags...>
{
template <typename T, vtkm::IdComponent NUM_COMPONENTS>
typename detail::ExtractComponentCompositeVecFunctor<T>::ResultArray operator()(
const vtkm::cont::ArrayHandle<vtkm::Vec<T, NUM_COMPONENTS>,
vtkm::cont::StorageTagCompositeVec<StorageTags...>>& src,
template <typename VecT>
auto operator()(
const vtkm::cont::ArrayHandle<VecT, vtkm::cont::StorageTagCompositeVec<StorageTags...>>& src,
vtkm::IdComponent componentIndex,
vtkm::CopyFlag allowCopy) const
{
using T = typename vtkm::VecTraits<VecT>::ComponentType;
vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<T, StorageTags>...> array(src);
constexpr vtkm::IdComponent NUM_SUB_COMPONENTS = vtkm::VecFlat<T>::NUM_COMPONENTS;

@ -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));
}

@ -138,6 +138,10 @@ public:
internal::ArrayPortalCounting<CountingValueType>(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

@ -249,9 +249,12 @@ VTKM_CONT vtkm::cont::ArrayHandleGroupVec<ArrayHandleType, NUM_COMPONENTS> make_
namespace internal
{
// Superclass will inherit the ArrayExtractComponentImplInefficient property if
// the sub-storage is inefficient (thus making everything inefficient).
template <typename ComponentsStorageTag, vtkm::IdComponent NUM_COMPONENTS>
struct ArrayExtractComponentImpl<
vtkm::cont::StorageTagGroupVec<ComponentsStorageTag, NUM_COMPONENTS>>
: vtkm::cont::internal::ArrayExtractComponentImpl<ComponentsStorageTag>
{
template <typename T>
vtkm::cont::ArrayHandleStride<typename vtkm::VecTraits<T>::BaseComponentType> operator()(

@ -216,6 +216,10 @@ class ArrayHandlePermutation
VTKM_IS_ARRAY_HANDLE(IndexArrayHandleType);
VTKM_IS_ARRAY_HANDLE(ValueArrayHandleType);
VTKM_STATIC_ASSERT_MSG(
(std::is_same<vtkm::Id, typename IndexArrayHandleType::ValueType>::value),
"Permutation array in ArrayHandlePermutation must have vtkm::Id value type.");
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandlePermutation,

@ -217,8 +217,11 @@ VTKM_CONT ArrayHandleReverse<HandleType> make_ArrayHandleReverse(const HandleTyp
namespace internal
{
// Superclass will inherit the ArrayExtractComponentImplInefficient property if
// the sub-storage is inefficient (thus making everything inefficient).
template <typename StorageTag>
struct ArrayExtractComponentImpl<vtkm::cont::StorageTagReverse<StorageTag>>
: vtkm::cont::internal::ArrayExtractComponentImpl<StorageTag>
{
template <typename T>
using StrideArrayType =

@ -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<ArrayHandleType> make_ArrayHandleView(const ArrayHandleType& arr
namespace internal
{
// Superclass will inherit the ArrayExtractComponentImplInefficient property if
// the sub-storage is inefficient (thus making everything inefficient).
template <typename StorageTag>
struct ArrayExtractComponentImpl<StorageTagView<StorageTag>>
: vtkm::cont::internal::ArrayExtractComponentImpl<StorageTag>
{
template <typename T>
using StrideArrayType =

@ -208,6 +208,15 @@ public:
FirstStorage::CreateWritePortal(FirstArrayBuffers(buffers), device, token),
SecondStorage::CreateWritePortal(SecondArrayBuffers(buffers), device, token));
}
vtkm::cont::ArrayHandle<T1, ST1> GetFirstArray(const vtkm::cont::internal::Buffer* buffers)
{
return { FirstArrayBuffers(buffers) };
}
vtkm::cont::ArrayHandle<T2, ST2> 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

@ -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

@ -10,6 +10,7 @@
#ifndef vtk_m_cont_DataSetBuilderRectilinear_h
#define vtk_m_cont_DataSetBuilderRectilinear_h
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/CoordinateSystem.h>
@ -34,7 +35,7 @@ class VTKM_CONT_EXPORT DataSetBuilderRectilinear
VTKM_CONT static void CopyInto(const vtkm::cont::ArrayHandle<T>& input,
vtkm::cont::ArrayHandle<U>& output)
{
vtkm::cont::UnknownArrayHandle(output).DeepCopyFrom(input);
vtkm::cont::ArrayCopy(input, output);
}
template <typename T, typename U>

@ -9,6 +9,7 @@
//============================================================================
#include <vtkm/cont/MergePartitionedDataSet.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
#include <vtkm/cont/ArrayHandleView.h>

@ -12,7 +12,6 @@
#define vtk_m_cont_ParticleArrayCopy_hxx
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/ParticleArrayCopy.h>
@ -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);
}

@ -21,7 +21,7 @@
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
@ -82,9 +82,8 @@ void PointLocatorSparseGrid::Build()
static_cast<vtkm::FloatDefault>(this->Range[2].Max));
// generate unique id for each input point
vtkm::cont::ArrayHandleCounting<vtkm::Id> 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;

@ -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<const UnknownArrayHandle*>(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<const UnknownArrayHandle*>(this)->CopyShallowIfPossible(source);
else
{
const_cast<const UnknownArrayHandle*>(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);
}
}

@ -113,6 +113,15 @@ void UnknownAHShallowCopy(const void* sourceMem, void* destinationMem)
*destination = *source;
}
template <typename T, typename S>
void UnknownAHDeepCopy(const void* sourceMem, void* destinationMem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
const AH* source = reinterpret_cast<const AH*>(sourceMem);
AH* destination = reinterpret_cast<AH*>(destinationMem);
destination->DeepCopyFrom(*source);
}
template <typename T, typename S>
std::vector<vtkm::cont::internal::Buffer>
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<vtkm::cont::internal::Buffer>(void*,
vtkm::IdComponent,
vtkm::CopyFlag);
@ -331,6 +343,7 @@ inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T>)
, Allocate(detail::UnknownAHAllocate<T, S>)
, ShallowCopy(detail::UnknownAHShallowCopy<T, S>)
, DeepCopy(detail::UnknownAHDeepCopy<T, S>)
, ExtractComponent(detail::UnknownAHExtractComponent<T, S>)
, ReleaseResources(detail::UnknownAHReleaseResources<T, S>)
, ReleaseResourcesExecution(detail::UnknownAHReleaseResourcesExecution<T, S>)

@ -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 <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayCopyDevice.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/DeviceAdapterList.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/internal/ArrayCopyUnknown.h>
#include <vtkm/worklet/WorkletMapField.h>
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 <typename InType, typename OutType>
VTKM_EXEC void operator()(const InType& in, OutType& out) const
{
out = in;
}
};
struct UnknownCopyOnDevice
{
bool Called = false;
template <typename InType, typename OutType>
void operator()(vtkm::cont::DeviceAdapterId device,
const vtkm::cont::ArrayHandleRecombineVec<InType>& in,
const vtkm::cont::ArrayHandleRecombineVec<OutType>& 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 <typename OutType, typename InType>
void operator()(const vtkm::cont::ArrayHandleRecombineVec<OutType>& out,
const vtkm::cont::ArrayHandleRecombineVec<InType>& 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 <typename InType>
void operator()(const vtkm::cont::ArrayHandleRecombineVec<InType>& in,
const vtkm::cont::UnknownArrayHandle& out) const
{
out.Allocate(in.GetNumberOfValues());
this->DoIt(in, out, typename std::is_same<vtkm::FloatDefault, InType>::type{});
}
template <typename InType>
void DoIt(const vtkm::cont::ArrayHandleRecombineVec<InType>& in,
const vtkm::cont::UnknownArrayHandle& out,
std::false_type) const
{
// Source is not float.
if (out.IsBaseComponentType<InType>())
{
// Arrays have the same base component type. Copy directly.
try
{
UnknownCopyFunctor2{}(out.ExtractArrayFromComponents<InType>(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<vtkm::FloatDefault>())
{
// Can copy anything to default float.
try
{
UnknownCopyFunctor2{}(
out.ExtractArrayFromComponents<vtkm::FloatDefault>(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 <typename InType>
void DoIt(const vtkm::cont::ArrayHandleRecombineVec<InType>& 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<vtkm::cont::ArrayHandleIndex>())
{
// Unlikely, but we'll check.
destination.AsArrayHandle<vtkm::cont::ArrayHandleIndex>().DeepCopyFrom(source);
}
else if (destination.IsBaseComponentType<vtkm::Id>())
{
destination.Allocate(source.GetNumberOfValues());
auto dest = destination.ExtractComponent<vtkm::Id>(0, vtkm::CopyFlag::Off);
vtkm::cont::ArrayCopyDevice(source, dest);
}
else if (destination.IsBaseComponentType<vtkm::IdComponent>())
{
destination.Allocate(source.GetNumberOfValues());
auto dest = destination.ExtractComponent<vtkm::IdComponent>(0, vtkm::CopyFlag::Off);
vtkm::cont::ArrayCopyDevice(source, dest);
}
else if (destination.CanConvert<vtkm::cont::ArrayHandle<vtkm::FloatDefault>>())
{
vtkm::cont::ArrayHandle<vtkm::FloatDefault> 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<vtkm::FloatDefault> dest;
vtkm::cont::ArrayCopyDevice(source, dest);
vtkm::cont::ArrayCopy(dest, destination);
}
}
template <typename ArrayHandleType>
bool TryArrayCopySpecialCase(const vtkm::cont::UnknownArrayHandle& source,
const vtkm::cont::UnknownArrayHandle& destination)
{
if (source.CanConvert<ArrayHandleType>())
{
ArrayCopySpecialCase(source.AsArrayHandle<ArrayHandleType>(), 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<vtkm::cont::ArrayHandleIndex>(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

@ -28,6 +28,7 @@ set(headers
FunctorsGeneral.h
IteratorFromArrayPortal.h
KXSort.h
MapArrayPermutation.h
OptionParser.h
OptionParserArguments.h
ParallelRadixSort.h

@ -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 <vtkm/cont/internal/CastInvalidValue.h>
#include <vtkm/cont/internal/MapArrayPermutation.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace
{
template <typename T>
struct MapPermutationWorklet : vtkm::worklet::WorkletMapField
{
T InvalidValue;
explicit MapPermutationWorklet(T invalidValue)
: InvalidValue(invalidValue)
{
}
using ControlSignature = void(FieldIn permutationIndex, WholeArrayIn input, FieldOut output);
template <typename InputPortalType, typename OutputType>
VTKM_EXEC void operator()(vtkm::Id permutationIndex,
InputPortalType inputPortal,
OutputType& output) const
{
VTKM_STATIC_ASSERT(vtkm::HasVecTraits<OutputType>::value);
if ((permutationIndex >= 0) && (permutationIndex < inputPortal.GetNumberOfValues()))
{
output = inputPortal.Get(permutationIndex);
}
else
{
output = this->InvalidValue;
}
}
};
struct DoMapFieldPermutation
{
template <typename InputArrayType, typename PermutationArrayType>
void operator()(const InputArrayType& input,
const PermutationArrayType& permutation,
vtkm::cont::UnknownArrayHandle& output,
vtkm::Float64 invalidValue) const
{
using BaseComponentType = typename InputArrayType::ValueType::ComponentType;
MapPermutationWorklet<BaseComponentType> worklet(
vtkm::cont::internal::CastInvalidValue<BaseComponentType>(invalidValue));
vtkm::cont::Invoker{}(
worklet,
permutation,
input,
output.ExtractArrayFromComponents<BaseComponentType>(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<vtkm::Id>())
{
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<vtkm::Id>(0), outputArray, invalidValue);
return outputArray;
}
}
}
} // namespace vtkm::cont::internal

@ -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 <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/vtkm_cont_export.h>
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 <typename T, typename S>
vtkm::cont::UnknownArrayHandle MapArrayPermutation(
const vtkm::cont::ArrayHandle<T,
vtkm::cont::StorageTagPermutation<vtkm::cont::StorageTagBasic, S>>&
inputArray,
vtkm::Float64 invalidValue = vtkm::Nan64())
{
vtkm::cont::ArrayHandlePermutation<vtkm::cont::ArrayHandle<vtkm::Id>,
vtkm::cont::ArrayHandle<T, S>>
input = inputArray;
return MapArrayPermutation(input.GetValueArray(), input.GetIndexArray(), invalidValue);
}
}
}
} // namespace vtkm::cont::internal
#endif //vtk_m_cont_internal_MapArrayPermutation_h

@ -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<std::pair<std::string, std::string>> 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());

@ -426,7 +426,7 @@ private:
SetPortal(basicArray.WritePortal());
vtkm::cont::ArrayHandleSOA<ValueType> 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<vtkm::IdComponent>(workIndex + 1);
vtkm::IdComponent expectedSize = static_cast<vtkm::IdComponent>(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<vtkm::Id> numComponentsArray;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleCounting<vtkm::IdComponent>(1, 1, ARRAY_SIZE),
numComponentsArray);
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray);
vtkm::cont::ArrayHandle<vtkm::Id> 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<vtkm::IdComponent>(workIndex + 1);
vtkm::IdComponent expectedSize = static_cast<vtkm::IdComponent>(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<vtkm::Id> numComponentsArray;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleCounting<vtkm::IdComponent>(1, 1, ARRAY_SIZE),
numComponentsArray);
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleIndex(ARRAY_SIZE), numComponentsArray);
vtkm::cont::ArrayHandle<vtkm::Id> 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);
}
}
};

@ -9,12 +9,18 @@
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayCopyDevice.h>
#include <vtkm/cont/ArrayHandleConcatenate.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleView.h>
#include <vtkm/cont/UncertainArrayHandle.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/VecTraits.h>
#include <vtkm/cont/testing/Testing.h>
@ -23,13 +29,43 @@ namespace
static constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename RefArrayType, typename TestArrayType>
void TestValues(const RefArrayType& refArray, const TestArrayType& testArray)
vtkm::cont::UnknownArrayHandle MakeComparable(const vtkm::cont::UnknownArrayHandle& array,
std::false_type)
{
return array;
}
template <typename T>
vtkm::cont::UnknownArrayHandle MakeComparable(const vtkm::cont::ArrayHandle<T>& array,
std::true_type)
{
return array;
}
template <typename ArrayType>
vtkm::cont::UnknownArrayHandle MakeComparable(const ArrayType& array, std::true_type)
{
vtkm::cont::ArrayHandle<typename ArrayType::ValueType> 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 <typename RefArrayType, typename TestArrayType>
void TestValues(const RefArrayType& refArray, const TestArrayType& testArray)
{
TestValuesImpl(
MakeComparable(refArray, typename vtkm::cont::internal::ArrayHandleCheck<RefArrayType>::type{}),
MakeComparable(testArray,
typename vtkm::cont::internal::ArrayHandleCheck<TestArrayType>::type{}));
}
template <typename ValueType>
vtkm::cont::ArrayHandle<ValueType> MakeInputArray()
{
@ -44,18 +80,20 @@ void TryCopy()
{
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
"Trying type: " << vtkm::testing::TypeName<ValueType>::Name());
using VTraits = vtkm::VecTraits<ValueType>;
{
std::cout << "implicit -> basic" << std::endl;
vtkm::cont::ArrayHandleIndex input(ARRAY_SIZE);
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayHandle<typename VTraits::BaseComponentType> output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
}
{
std::cout << "basic -> basic" << std::endl;
vtkm::cont::ArrayHandle<vtkm::Id> input = MakeInputArray<vtkm::Id>();
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::Id>;
vtkm::cont::ArrayHandle<SourceType> input = MakeInputArray<SourceType>();
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
@ -90,30 +128,72 @@ void TryCopy()
TestValues(input, output);
}
using TypeList = vtkm::ListAppend<vtkm::TypeListField, vtkm::List<ValueType, vtkm::UInt8>>;
using StorageList = VTKM_DEFAULT_STORAGE_LIST;
using UnknownArray = vtkm::cont::UnknownArrayHandle;
using UncertainArray = vtkm::cont::UncertainArrayHandle<TypeList, StorageList>;
{
std::cout << "unknown -> unknown" << std::endl;
UnknownArray input = MakeInputArray<ValueType>();
UnknownArray output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
}
{
std::cout << "uncertain -> basic (same type)" << std::endl;
UncertainArray input = MakeInputArray<ValueType>();
std::cout << "constant -> basic" << std::endl;
vtkm::cont::ArrayHandleConstant<ValueType> input(TestValue(2, ValueType{}), ARRAY_SIZE);
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
}
{
std::cout << "uncertain -> basic (different type)" << std::endl;
UncertainArray input = MakeInputArray<vtkm::UInt8>();
std::cout << "counting -> basic" << std::endl;
vtkm::cont::ArrayHandleCounting<ValueType> input(ValueType(-4), ValueType(3), ARRAY_SIZE);
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
}
{
std::cout << "view -> basic" << std::endl;
vtkm::cont::ArrayHandle<ValueType> input = MakeInputArray<ValueType>();
auto viewInput = vtkm::cont::make_ArrayHandleView(input, 1, ARRAY_SIZE / 2);
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
}
{
std::cout << "concatinate -> basic" << std::endl;
vtkm::cont::ArrayHandle<ValueType> input1 = MakeInputArray<ValueType>();
vtkm::cont::ArrayHandleConstant<ValueType> input2(TestValue(6, ValueType{}), ARRAY_SIZE / 2);
auto concatInput = vtkm::cont::make_ArrayHandleConcatenate(input1, input2);
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayCopy(concatInput, output);
TestValues(concatInput, output);
}
{
std::cout << "permutation -> basic" << std::endl;
vtkm::cont::ArrayHandle<vtkm::Id> indices;
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleCounting<vtkm::Id>(0, 2, ARRAY_SIZE / 2),
indices);
auto input = vtkm::cont::make_ArrayHandlePermutation(indices, MakeInputArray<ValueType>());
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
}
{
std::cout << "unknown -> unknown" << std::endl;
vtkm::cont::UnknownArrayHandle input = MakeInputArray<ValueType>();
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<ValueType>();
vtkm::cont::ArrayHandle<ValueType> output;
vtkm::cont::ArrayCopy(input, output);
TestValues(input, output);
}
{
std::cout << "unknown -> basic (different type)" << std::endl;
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::UInt8>;
vtkm::cont::UnknownArrayHandle input = MakeInputArray<SourceType>();
vtkm::cont::ArrayHandle<ValueType> 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<vtkm::UInt8> input = MakeInputArray<vtkm::UInt8>();
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::UInt8>;
vtkm::cont::ArrayHandle<SourceType> input = MakeInputArray<SourceType>();
vtkm::cont::ArrayHandle<ValueType> 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<vtkm::UInt8> input = MakeInputArray<vtkm::UInt8>();
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::UInt8>;
vtkm::cont::ArrayHandle<SourceType> input = MakeInputArray<SourceType>();
vtkm::cont::ArrayHandle<ValueType> outputArray;
vtkm::cont::UnknownArrayHandle(outputArray).CopyShallowIfPossible(input);
TestValues(input, outputArray);
@ -203,6 +285,8 @@ void TestArrayCopy()
TryCopy<vtkm::Id>();
TryCopy<vtkm::IdComponent>();
TryCopy<vtkm::Float32>();
TryCopy<vtkm::Vec3f>();
TryCopy<vtkm::Vec4i_16>();
TryArrayCopyShallowIfPossible();
}

@ -12,6 +12,7 @@
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayCopyDevice.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
@ -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<ValueType> copiedInExec;
vtkm::cont::ArrayCopy(decorArray, copiedInExec);
vtkm::cont::ArrayCopyDevice(decorArray, copiedInExec);
{
auto copiedPortal = copiedInExec.ReadPortal();
auto countPortal = ahCount.ReadPortal();

@ -8,7 +8,7 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayCopyDevice.h>
#include <vtkm/cont/ArrayHandleBasic.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
@ -84,13 +84,13 @@ void FillArray(vtkm::cont::ArrayHandle<T, S>& array)
using Traits = vtkm::VecTraits<T>;
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleConstant(T{}, ARRAY_SIZE), array);
array.AllocateAndFill(ARRAY_SIZE, vtkm::TypeTraits<T>::ZeroInitialization());
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
{
vtkm::cont::ArrayHandleRandomUniformReal<vtkm::Float64> randomArray(ARRAY_SIZE);
auto dest = vtkm::cont::make_ArrayHandleExtractComponent(array, component);
vtkm::cont::ArrayCopy(randomArray, dest);
vtkm::cont::ArrayCopyDevice(randomArray, dest);
}
}

@ -7,7 +7,7 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayCopyDevice.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
@ -143,16 +143,13 @@ auto PermutationArray = vtkm::cont::ArrayHandleCounting<vtkm::Id>(0, 2, BaseLine
vtkm::cont::CellSetExplicit<> MakeCellSetExplicit()
{
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant<vtkm::UInt8>{ vtkm::CELL_SHAPE_HEXAHEDRON,
BaseLineNumberOfCells },
shapes);
shapes.AllocateAndFill(BaseLineNumberOfCells, vtkm::CELL_SHAPE_HEXAHEDRON);
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
vtkm::cont::ArrayCopy(
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>{ 8, BaseLineNumberOfCells }, numIndices);
numIndices.AllocateAndFill(BaseLineNumberOfCells, 8);
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
vtkm::cont::ArrayCopy(BaseLineConnectivity, connectivity);
vtkm::cont::ArrayCopyDevice(BaseLineConnectivity, connectivity);
auto offsets = vtkm::cont::ConvertNumComponentsToOffsets(numIndices);

@ -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)

@ -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 <vtkm/filter/FilterDataSet.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/connected_components/CellSetConnectivity.h>
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<CellSetConnectivity>
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 <typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<Policy> policy);
template <typename Policy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<Policy>&)
{
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 <vtkm/filter/CellSetConnectivity.hxx>
}
} // namespace vtkm::filter
#endif //vtkm_m_filter_CellSetConnectivity_h
#endif //vtk_m_filter_CellSetConnectivity_h

@ -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 <vtkm/filter/CreateResult.h>
#include <vtkm/worklet/connectivities/CellSetConnectivity.h>
namespace vtkm
{
namespace filter
{
VTKM_CONT CellSetConnectivity::CellSetConnectivity()
: OutputFieldName("component")
{
}
template <typename Policy>
inline VTKM_CONT vtkm::cont::DataSet CellSetConnectivity::DoExecute(
const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<Policy> policy)
{
vtkm::cont::ArrayHandle<vtkm::Id> 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

@ -11,133 +11,31 @@
#ifndef vtk_m_filter_CrossProduct_h
#define vtk_m_filter_CrossProduct_h
#include <vtkm/filter/FilterField.h>
#include <vtkm/worklet/CrossProduct.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/vector_calculus/CrossProduct.h>
namespace vtkm
{
namespace filter
{
class CrossProduct : public vtkm::filter::FilterField<CrossProduct>
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 <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> 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 <vtkm/filter/CrossProduct.hxx>
#endif // vtk_m_filter_CrossProduct_h

@ -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 <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/worklet/DispatcherMapField.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT CrossProduct::CrossProduct()
: vtkm::filter::FilterField<CrossProduct>()
, SecondaryFieldName()
, SecondaryFieldAssociation(vtkm::cont::Field::Association::ANY)
, UseCoordinateSystemAsSecondaryField(false)
, SecondaryCoordinateSystemIndex(0)
{
this->SetOutputFieldName("crossproduct");
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet CrossProduct::DoExecute(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>, StorageType>& primary,
const vtkm::filter::FieldMetadata& fieldMetadata,
vtkm::filter::PolicyBase<DerivedPolicy> 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<vtkm::Vec<T, 3>>(secondaryField, policy, *this);
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>> output;
this->Invoke(vtkm::worklet::CrossProduct{}, primary, secondary, output);
return CreateResult(inDataSet, output, this->GetOutputFieldName(), fieldMetadata);
}
}
} // namespace vtkm::filter
#endif

@ -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 <vtkm/filter/FilterField.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/density_estimate/Entropy.h>
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<Entropy>
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 <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& 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 <vtkm/filter/Entropy.hxx>
#endif // vtk_m_filter_Entropy_h
#endif //vtk_m_filter_Entropy_h

@ -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 <vtkm/worklet/FieldEntropy.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT Entropy::Entropy()
: NumberOfBins(10)
{
this->SetOutputFieldName("entropy");
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet Entropy::DoExecute(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMetadata,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
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<vtkm::Float64> entropy;
entropy.Allocate(1);
entropy.WritePortal().Set(0, e);
return CreateResult(inDataSet, entropy, this->GetOutputFieldName(), fieldMetadata);
}
}
} // namespace vtkm::filter
#endif

@ -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 <vtkm/filter/ExtractGeometry.h>
#include <vtkm/filter/ExtractGeometry.hxx>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
ExtractGeometry::ExtractGeometry()
: vtkm::filter::FilterDataSet<ExtractGeometry>()
, 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<vtkm::Id> 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<vtkm::filter::PolicyDefault> policy);
}
} // namespace vtkm::filter

@ -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 <vtkm/filter/vtkm_filter_common_export.h>
#include <vtkm/ImplicitFunction.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/ExtractGeometry.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/ExtractGeometry.h>
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<ExtractGeometry>
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 <typename DerivedPolicy>
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
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<vtkm::filter::PolicyDefault>);
#endif
}
} // namespace vtkm::filter
#endif // vtk_m_filter_ExtractGeometry_h
#endif //vtk_m_filter_ExtractGeometry_h

@ -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 <vtkm/filter/ExtractStructured.h>
#include <vtkm/filter/ExtractStructured.hxx>
#include <vtkm/filter/MapFieldPermutation.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
ExtractStructured::ExtractStructured()
: vtkm::filter::FilterDataSet<ExtractStructured>()
, 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<vtkm::filter::PolicyDefault> policy);
}
}

@ -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 <vtkm/filter/vtkm_filter_common_export.h>
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/ExtractStructured.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/ExtractStructured.h>
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<ExtractStructured>
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 <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result, const vtkm::cont::Field& field);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return this->MapFieldOntoOutput(result, field);
}
VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet&,
vtkm::cont::PartitionedDataSet&);
template <typename DerivedPolicy>
VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input,
vtkm::cont::PartitionedDataSet& output,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
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<vtkm::Id> CellFieldMap;
vtkm::cont::ArrayHandle<vtkm::Id> 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<vtkm::filter::PolicyDefault>);
#endif
}
} // namespace vtkm::filter
#endif // vtk_m_filter_ExtractStructured_h
#endif //vtk_m_filter_ExtractStructured_h

@ -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 <vtkm/filter/ExtractStructured.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
vtkm::cont::DataSet ExtractStructured::DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> 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

@ -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 <vtkm/CellClassification.h>
#include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/filter/Threshold.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/GhostCellRemove.h>
namespace vtkm
{
namespace filter
{
struct GhostCellRemovePolicy : vtkm::filter::PolicyBase<GhostCellRemovePolicy>
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<vtkm::UInt8>;
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<GhostCellRemove>
{
public:
//currently the GhostCellRemove filter only works on uint8 data.
using SupportedTypes = vtkm::List<vtkm::UInt8>;
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 <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid after DoExecute is run
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private:
bool RemoveAll;
bool RemoveField;
vtkm::UInt8 RemoveVals;
vtkm::worklet::Threshold Worklet;
};
}
} // namespace vtkm::filter
#ifndef vtk_m_filter_GhostCellRemove_hxx
#include <vtkm/filter/GhostCellRemove.hxx>
#endif
#endif // vtk_m_filter_GhostCellRemove_h
#endif //vtk_m_filter_GhostCellRemove_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 <vtkm/filter/FilterField.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/density_estimate/Histogram.h>
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<Histogram>
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 <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> 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 <typename DerivedPolicy>
VTKM_CONT void PreExecute(const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
template <typename DerivedPolicy>
VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input,
vtkm::cont::PartitionedDataSet& output,
const vtkm::filter::PolicyBase<DerivedPolicy>&);
//@}
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 <vtkm/filter/Histogram.hxx>
#endif // vtk_m_filter_Histogram_h
#endif //vtk_m_filter_Histogram_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 <vtkm/filter/FilterField.h>
#include <vtkm/worklet/connectivities/ImageConnectivity.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/connected_components/ImageConnectivity.h>
/// \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<ImageConnectivity>
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 <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMetadata,
const vtkm::filter::PolicyBase<DerivedPolicy>&);
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 <vtkm/filter/ImageConnectivity.hxx>
#endif //vtk_m_filter_ImageConnectivity_h

@ -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 <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet ImageConnectivity::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMetadata,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
{
if (!fieldMetadata.IsPointField())
{
throw vtkm::cont::ErrorBadValue("Active field for ImageConnectivity must be a point field.");
}
vtkm::cont::ArrayHandle<vtkm::Id> 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

@ -8,65 +8,11 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/VecTraits.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/internal/CastInvalidValue.h>
#include <vtkm/cont/internal/MapArrayPermutation.h>
#include <vtkm/filter/MapFieldPermutation.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace
{
template <typename T>
struct MapPermutationWorklet : vtkm::worklet::WorkletMapField
{
T InvalidValue;
explicit MapPermutationWorklet(T invalidValue)
: InvalidValue(invalidValue)
{
}
using ControlSignature = void(FieldIn permutationIndex, WholeArrayIn input, FieldOut output);
template <typename InputPortalType, typename OutputType>
VTKM_EXEC void operator()(vtkm::Id permutationIndex,
InputPortalType inputPortal,
OutputType& output) const
{
VTKM_STATIC_ASSERT(vtkm::HasVecTraits<OutputType>::value);
if ((permutationIndex >= 0) && (permutationIndex < inputPortal.GetNumberOfValues()))
{
output = inputPortal.Get(permutationIndex);
}
else
{
output = this->InvalidValue;
}
}
};
struct DoMapFieldPermutation
{
template <typename InputArrayType>
void operator()(const InputArrayType& input,
const vtkm::cont::ArrayHandle<vtkm::Id>& permutation,
vtkm::cont::UnknownArrayHandle& output,
vtkm::Float64 invalidValue) const
{
using BaseComponentType = typename InputArrayType::ValueType::ComponentType;
MapPermutationWorklet<BaseComponentType> worklet(
vtkm::cont::internal::CastInvalidValue<BaseComponentType>(invalidValue));
vtkm::cont::Invoker{}(
worklet,
permutation,
input,
output.ExtractArrayFromComponents<BaseComponentType>(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;
}

@ -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 <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/Mask.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/Mask.h>
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<Mask>
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 <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
//Map a new field onto the resulting dataset after running the filter
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> 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 <vtkm/filter/Mask.hxx>
#endif // vtk_m_filter_Mask_h
#endif //vtk_m_filter_Mask_h

@ -10,41 +10,30 @@
#ifndef vtk_m_filter_NDEntropy_h
#define vtk_m_filter_NDEntropy_h
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/density_estimate/NDEntropy.h>
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<NDEntropy>
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 <typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> policy);
template <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private:
std::vector<vtkm::Id> NumOfBins;
std::vector<std::string> 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 <vtkm/filter/NDEntropy.hxx>
#endif //vtk_m_filter_NDEntropy_h

@ -10,61 +10,31 @@
#ifndef vtk_m_filter_NDHistogram_h
#define vtk_m_filter_NDHistogram_h
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/density_estimate/NDHistogram.h>
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<NDHistogram>
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 <typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> 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 <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy> policy);
private:
std::vector<vtkm::Id> NumOfBins;
std::vector<std::string> FieldNames;
std::vector<vtkm::Float64> BinDeltas;
std::vector<vtkm::Range> 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 <vtkm/filter/NDHistogram.hxx>
#endif //vtk_m_filter_NDHistogram_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);

@ -142,6 +142,54 @@ protected:
}
}
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCallScalarField(const vtkm::cont::UnknownArrayHandle& fieldArray,
Functor&& functor,
Args&&... args) const
{
fieldArray
.CastAndCallForTypesWithFloatFallback<vtkm::TypeListFieldScalar, VTKM_DEFAULT_STORAGE_LIST>(
std::forward<Functor>(functor), std::forward<Args>(args)...);
}
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCallScalarField(const vtkm::cont::Field& field,
Functor&& functor,
Args&&... args) const
{
this->CastAndCallScalarField(
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
}
private:
template <vtkm::IdComponent VecSize>
struct ScalarToVec
{
template <typename T>
using type = vtkm::Vec<T, VecSize>;
};
protected:
template <vtkm::IdComponent VecSize, typename Functor, typename... Args>
VTKM_CONT void CastAndCallVecField(const vtkm::cont::UnknownArrayHandle& fieldArray,
Functor&& functor,
Args&&... args) const
{
using VecList =
vtkm::ListTransform<vtkm::TypeListFieldScalar, ScalarToVec<VecSize>::template type>;
fieldArray.CastAndCallForTypesWithFloatFallback<VecList, VTKM_DEFAULT_STORAGE_LIST>(
std::forward<Functor>(functor), std::forward<Args>(args)...);
}
template <vtkm::IdComponent VecSize, typename Functor, typename... Args>
VTKM_CONT void CastAndCallVecField(const vtkm::cont::Field& field,
Functor&& functor,
Args&&... args) const
{
this->CastAndCallVecField<VecSize>(
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
}
private:
void ResizeIfNeeded(size_t index_st);

@ -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 <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{
namespace filter
{
// We only need the CoordinateSystem and scalar fields of the input dataset thus a FilterField
template <typename Derived>
class ParticleDensityBase : public vtkm::filter::FilterDataSetWithField<Derived>
{
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<vtkm::FloatDefault>(bounds.X.Min),
static_cast<vtkm::FloatDefault>(bounds.Y.Min),
static_cast<vtkm::FloatDefault>(bounds.Z.Min) })
, Spacing(vtkm::Vec3f{ static_cast<vtkm::FloatDefault>(bounds.X.Length()),
static_cast<vtkm::FloatDefault>(bounds.Y.Length()),
static_cast<vtkm::FloatDefault>(bounds.Z.Length()) } /
Dimension)
, ComputeNumberDensity(false)
, DivideByVolume(true)
{
}
public:
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
if (this->ComputeNumberDensity)
{
return static_cast<Derived*>(this)->DoExecute(
input,
vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 }, input.GetNumberOfPoints()),
vtkm::filter::FieldMetadata{}, // Ignored
policy);
}
else
{
return this->FilterDataSetWithField<Derived>::PrepareForExecution(input, policy);
}
}
template <typename T, typename StorageType, typename Policy>
VTKM_CONT bool DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
vtkm::filter::PolicyBase<Policy>)
{
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 <typename T>
VTKM_EXEC void operator()(T& value) const
{
value = static_cast<T>(value / Volume);
}
private:
vtkm::Float64 Volume;
}; // class DivideByVolumeWorklet
};
}
}
#endif //vtk_m_filter_particle_density_base_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 <vtkm/filter/ParticleDensityBase.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/density_estimate/ParticleDensityCloudInCell.h>
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<ParticleDensityCloudInCell>
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>;
ParticleDensityCloudInCell_deprecated();
}
ParticleDensityCloudInCell(const vtkm::Id3& dimension,
const vtkm::Vec3f& origin,
const vtkm::Vec3f& spacing);
ParticleDensityCloudInCell(const Id3& dimension, const vtkm::Bounds& bounds);
template <typename T, typename StorageType, typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<Policy> 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 <vtkm/filter/ParticleDensityCloudInCell.hxx>
#endif // vtk_m_filter_particle_density_cic_h
}
} // namespace vtkm::filter
#endif //vtk_m_filter_ParticleDensityCloudInCell_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 <vtkm/filter/ParticleDensityBase.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h>
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<ParticleDensityNearestGridPoint>
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>;
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 <typename T, typename StorageType, typename Policy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<Policy> 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 <vtkm/filter/ParticleDensityNearestGridPoint.hxx>
}
} // namespace vtkm::filter
#endif //vtk_m_filter_particle_density_ngp_h
#endif //vtk_m_filter_ParticleDensityNearestGridPoint_h

@ -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 <vtkm/filter/Threshold.h>
#include <vtkm/filter/MapFieldPermutation.h>
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);
}
}

@ -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 <vtkm/filter/vtkm_filter_common_export.h>
#include <vtkm/filter/FilterDataSetWithField.h>
#include <vtkm/worklet/Threshold.h>
#include <vtkm/Deprecated.h>
#include <vtkm/filter/entity_extraction/Threshold.h>
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<Threshold>
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 <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> 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 <typename DerivedPolicy>
VTKM_CONT bool MapFieldOntoOutput(vtkm::cont::DataSet& result,
const vtkm::cont::Field& field,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
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 <vtkm/filter/Threshold.hxx>
#endif // vtk_m_filter_Threshold_h
#endif //vtk_m_filter_Threshold_h

@ -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 <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/UnknownCellSet.h>
namespace
{
class ThresholdRange
{
public:
VTKM_CONT
ThresholdRange(const vtkm::Float64& lower, const vtkm::Float64& upper)
: Lower(lower)
, Upper(upper)
{
}
template <typename T>
VTKM_EXEC bool operator()(const T& value) const
{
return value >= static_cast<T>(this->Lower) && value <= static_cast<T>(this->Upper);
}
//Needed to work with ArrayHandleVirtual
template <typename PortalType>
VTKM_EXEC bool operator()(
const vtkm::internal::ArrayPortalValueReference<PortalType>& value) const
{
using T = typename PortalType::ValueType;
return value.Get() >= static_cast<T>(this->Lower) && value.Get() <= static_cast<T>(this->Upper);
}
private:
vtkm::Float64 Lower;
vtkm::Float64 Upper;
};
} // end anon namespace
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy>
vtkm::cont::DataSet Threshold::DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> 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

@ -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

@ -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
)

@ -10,7 +10,7 @@
#ifndef vtk_m_worklet_RemoveUnusedPoints_h
#define vtk_m_worklet_RemoveUnusedPoints_h
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayCopyDevice.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
@ -102,9 +102,7 @@ public:
if (this->MaskArray.GetNumberOfValues() < 1)
{
// Initialize mask array to 0.
vtkm::cont::ArrayCopy(
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>(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<InT, InS>& inArray,
vtkm::cont::ArrayHandle<OutT, OutS>& outArray) const
{
vtkm::cont::ArrayCopy(this->MapPointFieldShallow(inArray), outArray);
vtkm::cont::ArrayCopyDevice(this->MapPointFieldShallow(inArray), outArray);
}
template <typename T, typename S>

@ -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 ()

@ -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 <vtkm/filter/CreateResult.h>
#include <vtkm/filter/connected_components/CellSetConnectivity.h>
#include <vtkm/filter/connected_components/worklet/CellSetConnectivity.h>
namespace vtkm
{
namespace filter
{
namespace connected_components
{
VTKM_CONT vtkm::cont::DataSet CellSetConnectivity::DoExecute(const vtkm::cont::DataSet& input)
{
vtkm::cont::ArrayHandle<vtkm::Id> 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

@ -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 <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/connected_components/vtkm_filter_connected_components_export.h>
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

@ -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 <vtkm/filter/CreateResult.h>
#include <vtkm/filter/connected_components/ImageConnectivity.h>
#include <vtkm/filter/connected_components/worklet/ImageConnectivity.h>
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<vtkm::Id> 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

@ -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 <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/connected_components/vtkm_filter_connected_components_export.h>
/// \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

@ -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
)

@ -8,11 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CellSetConnectivity.h>
#include <vtkm/filter/connected_components/CellSetConnectivity.h>
#include <vtkm/filter/contour/Contour.h>
#include <vtkm/source/Tangle.h>
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<vtkm::Id> 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<vtkm::Id> 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<vtkm::Id> componentArray;

@ -8,7 +8,7 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/filter/ImageConnectivity.h>
#include <vtkm/filter/connected_components/ImageConnectivity.h>
#include <vtkm/cont/DataSet.h>
@ -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);

@ -10,8 +10,8 @@
#ifndef vtk_m_worklet_connectivity_CellSetConnectivity_h
#define vtk_m_worklet_connectivity_CellSetConnectivity_h
#include <vtkm/worklet/connectivities/CellSetDualGraph.h>
#include <vtkm/worklet/connectivities/GraphConnectivity.h>
#include <vtkm/filter/connected_components/worklet/CellSetDualGraph.h>
#include <vtkm/filter/connected_components/worklet/GraphConnectivity.h>
namespace vtkm
{

@ -12,9 +12,9 @@
#define vtk_m_worklet_connectivity_graph_connectivity_h
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/connectivities/CellSetDualGraph.h>
#include <vtkm/worklet/connectivities/InnerJoin.h>
#include <vtkm/worklet/connectivities/UnionFind.h>
#include <vtkm/filter/connected_components/worklet/CellSetDualGraph.h>
#include <vtkm/filter/connected_components/worklet/InnerJoin.h>
#include <vtkm/filter/connected_components/worklet/UnionFind.h>
namespace vtkm
{

@ -11,14 +11,15 @@
#ifndef vtk_m_worklet_connectivity_ImageConnectivity_h
#define vtk_m_worklet_connectivity_ImageConnectivity_h
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/UncertainArrayHandle.h>
#include <vtkm/cont/UncertainCellSet.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletPointNeighborhood.h>
#include <vtkm/worklet/connectivities/InnerJoin.h>
#include <vtkm/worklet/connectivities/UnionFind.h>
#include <vtkm/filter/connected_components/worklet/InnerJoin.h>
#include <vtkm/filter/connected_components/worklet/UnionFind.h>
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 <typename Boundary,
typename NeighborComp,
typename NeighborColor,
@ -80,7 +81,7 @@ public:
}
}
};
}
} // namespace detail
// Single pass connected component algorithm from
// Jaiganesh, Jayadharini, and Martin Burtscher.
@ -153,8 +154,8 @@ public:
.CastAndCall(ResolveUnknownCellSet(), pixels, componentsOut);
}
};
}
}
}
} // namespace connectivity
} // namespace worklet
} // namespace vtkm
#endif // vtk_m_worklet_connectivity_ImageConnectivity_h

@ -36,7 +36,7 @@ set_property(TARGET
PROPERTY UNITY_BUILD_MODE GROUP
)
target_link_libraries(vtkm_filter_contour PUBLIC vtkm_worklet vtkm_filter_core)
target_link_libraries(vtkm_filter_contour PRIVATE vtkm_worklet PUBLIC vtkm_filter_core)
if (VTKm_ENABLE_MPI)
target_link_libraries(vtkm_filter_contour PUBLIC MPI::MPI_CXX)

@ -17,6 +17,7 @@
#include <vtkm/filter/contour/worklet/FlyingEdgesPass2.h>
#include <vtkm/filter/contour/worklet/FlyingEdgesPass4.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandleGroupVec.h>
#include <vtkm/cont/Invoker.h>

@ -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 ()

@ -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 <vtkm/filter/CreateResult.h>
#include <vtkm/filter/density_estimate/Entropy.h>
#include <vtkm/filter/density_estimate/worklet/FieldEntropy.h>
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<vtkm::TypeListFieldScalar, VTKM_DEFAULT_STORAGE_LIST>(
resolveType);
//the entropy vector only contain one element, the entropy of the input field
vtkm::cont::ArrayHandle<vtkm::Float64> 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

@ -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 <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/density_estimate/vtkm_filter_density_estimate_export.h>
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

@ -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 <vtkm/worklet/FieldHistogram.h>
#include <vtkm/filter/density_estimate/Histogram.h>
#include <vtkm/filter/density_estimate/worklet/FieldHistogram.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/AssignerPartitionedDataSet.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/ErrorFilterExecution.h>
@ -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 <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet Histogram::DoExecute(
const vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata&,
vtkm::filter::PolicyBase<DerivedPolicy>)
VTKM_CONT vtkm::cont::DataSet Histogram::DoExecute(const vtkm::cont::DataSet& input)
{
vtkm::cont::ArrayHandle<vtkm::Id> binArray;
T delta;
vtkm::worklet::FieldHistogram worklet;
if (this->ComputedRange.IsNonEmpty())
{
worklet.Run(field,
this->NumberOfBins,
static_cast<T>(this->ComputedRange.Min),
static_cast<T>(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<decltype(concrete)>::ValueType;
T delta;
vtkm::worklet::FieldHistogram worklet;
if (this->ComputedRange.IsNonEmpty())
{
worklet.Run(concrete,
this->NumberOfBins,
static_cast<T>(this->ComputedRange.Min),
static_cast<T>(this->ComputedRange.Max),
delta,
binArray);
}
else
{
worklet.Run(concrete, this->NumberOfBins, this->ComputedRange, delta, binArray);
}
this->BinDelta = static_cast<vtkm::Float64>(delta);
};
const auto& fieldArray = this->GetFieldFromDataSet(input).GetData();
fieldArray
.CastAndCallForTypesWithFloatFallback<vtkm::TypeListFieldScalar, VTKM_DEFAULT_STORAGE_LIST>(
resolveType);
this->BinDelta = static_cast<vtkm::Float64>(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 <typename DerivedPolicy>
inline VTKM_CONT void Histogram::PreExecute(const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
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 <typename DerivedPolicy>
inline VTKM_CONT void Histogram::PostExecute(const vtkm::cont::PartitionedDataSet&,
vtkm::cont::PartitionedDataSet& result,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
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

@ -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 <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/density_estimate/vtkm_filter_density_estimate_export.h>
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

@ -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 <vtkm/cont/DataSet.h>
#include <vtkm/worklet/NDimsEntropy.h>
#include <vtkm/filter/density_estimate/NDEntropy.h>
#include <vtkm/filter/density_estimate/worklet/NDimsEntropy.h>
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 <typename Policy>
inline VTKM_CONT vtkm::cont::DataSet NDEntropy::DoExecute(
const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> 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 <typename DerivedPolicy>
inline VTKM_CONT bool NDEntropy::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::Field&,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return false;
}
}
}
#endif
} // namespace density_estimate
} // namespace filter
} // namespace vtkm

@ -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 <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/density_estimate/vtkm_filter_density_estimate_export.h>
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<vtkm::Id> NumOfBins;
std::vector<std::string> FieldNames;
};
}
}
} // namespace vtkm::filter
#endif //vtk_m_filter_density_estimate_NDEntropy_h

@ -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 <vector>
#include <vtkm/cont/DataSet.h>
#include <vtkm/worklet/NDimsHistogram.h>
#include <vtkm/filter/density_estimate/NDHistogram.h>
#include <vtkm/filter/density_estimate/worklet/NDimsHistogram.h>
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 <typename Policy>
inline VTKM_CONT vtkm::cont::DataSet NDHistogram::DoExecute(const vtkm::cont::DataSet& inData,
vtkm::filter::PolicyBase<Policy> 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 <typename DerivedPolicy>
inline VTKM_CONT bool NDHistogram::MapFieldOntoOutput(vtkm::cont::DataSet&,
const vtkm::cont::Field&,
vtkm::filter::PolicyBase<DerivedPolicy>)
{
return false;
}
}
}
#endif
} // namespace density_estimate
} // namespace filter
} // namespace vtkm

@ -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 <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/density_estimate/vtkm_filter_density_estimate_export.h>
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<vtkm::Id> NumOfBins;
std::vector<std::string> FieldNames;
std::vector<vtkm::Float64> BinDeltas;
std::vector<vtkm::Range> DataRanges; //Min Max of the field
};
} // namespace density_estimate
} // namespace filter
} // namespace vtm
#endif //vtk_m_filter_density_estimate_NDHistogram_h

@ -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 <vtkm/filter/density_estimate/ParticleDensityBase.h>
#include <vtkm/worklet/WorkletMapField.h>
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 <typename T>
VTKM_EXEC void operator()(T& value) const
{
value = static_cast<T>(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

@ -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 <vtkm/filter/NewFilterField.h>
#include <vtkm/filter/density_estimate/vtkm_filter_density_estimate_export.h>
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<vtkm::FloatDefault>(bounds.X.Min),
static_cast<vtkm::FloatDefault>(bounds.Y.Min),
static_cast<vtkm::FloatDefault>(bounds.Z.Min) })
, Spacing(vtkm::Vec3f{ static_cast<vtkm::FloatDefault>(bounds.X.Length()),
static_cast<vtkm::FloatDefault>(bounds.Y.Length()),
static_cast<vtkm::FloatDefault>(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

@ -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 <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/CellLocatorUniformGrid.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/density_estimate/ParticleDensityCloudInCell.h>
#include <vtkm/worklet/WorkletMapField.h>
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 <typename T, typename StorageType, typename Policy>
inline VTKM_CONT vtkm::cont::DataSet ParticleDensityCloudInCell::DoExecute(
const cont::DataSet& dataSet,
const cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata&,
PolicyBase<Policy>)
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<T> density;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant<T>(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<decltype(concrete)>::ValueType;
this->Invoke(vtkm::worklet::CICWorklet{},
coords,
field,
locator,
uniform.GetCellSet().template AsCellSet<vtkm::cont::CellSetStructured<3>>(),
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<T> 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<vtkm::cont::CellSetStructured<3>>(),
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<VTKM_DEFAULT_STORAGE_LIST, vtkm::List<vtkm::cont::StorageTagConstant>>>(
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

@ -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 <vtkm/filter/density_estimate/ParticleDensityBase.h>
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

@ -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 <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/CellLocatorUniformGrid.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/filter/PolicyBase.h>
#include <vtkm/filter/density_estimate/ParticleDensityNearestGridPoint.h>
#include <vtkm/worklet/WorkletMapField.h>
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 <typename T, typename StorageType, typename Policy>
inline VTKM_CONT vtkm::cont::DataSet ParticleDensityNearestGridPoint::DoExecute(
const vtkm::cont::DataSet& dataSet,
const vtkm::cont::ArrayHandle<T, StorageType>&
field, // particles' scala field to be deposited to the mesh, e.g. mass or charge
const vtkm::filter::FieldMetadata&,
vtkm::filter::PolicyBase<Policy>)
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<T> density;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant<T>(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<decltype(concrete)>::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<T> 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<VTKM_DEFAULT_STORAGE_LIST, vtkm::List<vtkm::cont::StorageTagConstant>>>(
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
}

@ -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 <vtkm/filter/density_estimate/ParticleDensityBase.h>
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

@ -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
)

@ -8,7 +8,7 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/filter/Entropy.h>
#include <vtkm/filter/density_estimate/Entropy.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/testing/Testing.h>
@ -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

Some files were not shown because too many files have changed in this diff Show More