mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge topic 'advanced-compute-range'
01bacbcde Advanced Compute Range Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Kenneth Moreland <morelandkd@ornl.gov> Merge-request: !3082
This commit is contained in:
commit
90f09e8bcc
21
docs/changelog/advanced-compute-range.md
Normal file
21
docs/changelog/advanced-compute-range.md
Normal file
@ -0,0 +1,21 @@
|
||||
# New features for computing array ranges
|
||||
|
||||
ArrayRangeCompute has been update to support more features that are present
|
||||
in VTK and ParaView.
|
||||
|
||||
New overloads for `ArrayRangeCompute` have been added:
|
||||
1. Takes a boolean parameter, `computeFiniteRange`, that specifies
|
||||
whether to compute only the finite range by ignoring any non-finite values (+/-inf)
|
||||
in the array.
|
||||
|
||||
2. Takes a `maskArray` parameter of type `vtkm::cont::ArrayHandle<vtkm::UInt8>`.
|
||||
The mask array must contain the same number of elements as the input array.
|
||||
A value in the input array is treated as masked off if the
|
||||
corresponding value in the mask array is non-zero. Masked off values are ignored
|
||||
in the range computation.
|
||||
|
||||
A new function `ArrayRangeComputeMagnitude` has been added. If the input array
|
||||
has multiple components, this function computes the range of the magnitude of
|
||||
the values of the array. Nested Vecs are treated as flat. A single `Range` object
|
||||
is returned containing the result. `ArrayRangeComputMagnitude` also has similar
|
||||
overloads as `ArrayRangeCompute`.
|
@ -484,6 +484,13 @@ struct ArrayExtractComponentImpl<vtkm::cont::StorageTagCartesianProduct<STs...>>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeGeneric(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device);
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl;
|
||||
|
||||
@ -494,63 +501,43 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagCartesianPro
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>,
|
||||
vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>& input_,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
if (maskArray.GetNumberOfValues() != 0)
|
||||
{
|
||||
return vtkm::cont::internal::ArrayRangeComputeGeneric(
|
||||
input_, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
const auto& input =
|
||||
static_cast<const vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
|
||||
vtkm::cont::ArrayHandle<T, ST2>,
|
||||
vtkm::cont::ArrayHandle<T, ST3>>&>(
|
||||
input_);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ranges[3];
|
||||
ranges[0] = vtkm::cont::internal::ArrayRangeComputeImpl<ST1>{}(
|
||||
input.GetFirstArray(), maskArray, computeFiniteRange, device);
|
||||
ranges[1] = vtkm::cont::internal::ArrayRangeComputeImpl<ST2>{}(
|
||||
input.GetSecondArray(), maskArray, computeFiniteRange, device);
|
||||
ranges[2] = vtkm::cont::internal::ArrayRangeComputeImpl<ST3>{}(
|
||||
input.GetThirdArray(), maskArray, computeFiniteRange, device);
|
||||
|
||||
auto numComponents =
|
||||
ranges[0].GetNumberOfValues() + ranges[1].GetNumberOfValues() + ranges[2].GetNumberOfValues();
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(3);
|
||||
result.Allocate(numComponents);
|
||||
auto resultPortal = result.WritePortal();
|
||||
|
||||
const vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
|
||||
vtkm::cont::ArrayHandle<T, ST2>,
|
||||
vtkm::cont::ArrayHandle<T, ST3>>& input = input_;
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> componentRangeArray;
|
||||
|
||||
vtkm::IdComponent index = 0;
|
||||
vtkm::cont::ArrayHandle<T, ST1> firstArray = input.GetFirstArray();
|
||||
componentRangeArray = vtkm::cont::internal::ArrayRangeComputeImpl<ST1>{}(firstArray, device);
|
||||
vtkm::Id numSubComponents = componentRangeArray.GetNumberOfValues();
|
||||
if (numSubComponents > 1)
|
||||
for (vtkm::Id i = 0, index = 0; i < 3; ++i)
|
||||
{
|
||||
result.Allocate(result.GetNumberOfValues() + numSubComponents - 1, vtkm::CopyFlag::On);
|
||||
resultPortal = result.WritePortal();
|
||||
auto rangePortal = ranges[i].ReadPortal();
|
||||
for (vtkm::Id j = 0; j < rangePortal.GetNumberOfValues(); ++j, ++index)
|
||||
{
|
||||
resultPortal.Set(index, rangePortal.Get(j));
|
||||
}
|
||||
}
|
||||
auto componentRangePortal = componentRangeArray.ReadPortal();
|
||||
for (vtkm::IdComponent subComponent = 0; subComponent < numSubComponents; ++subComponent)
|
||||
{
|
||||
resultPortal.Set(index, componentRangePortal.Get(subComponent));
|
||||
++index;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<T, ST2> secondArray = input.GetSecondArray();
|
||||
componentRangeArray = vtkm::cont::internal::ArrayRangeComputeImpl<ST2>{}(secondArray, device);
|
||||
numSubComponents = componentRangeArray.GetNumberOfValues();
|
||||
if (numSubComponents > 1)
|
||||
{
|
||||
result.Allocate(result.GetNumberOfValues() + numSubComponents - 1, vtkm::CopyFlag::On);
|
||||
resultPortal = result.WritePortal();
|
||||
}
|
||||
componentRangePortal = componentRangeArray.ReadPortal();
|
||||
for (vtkm::IdComponent subComponent = 0; subComponent < numSubComponents; ++subComponent)
|
||||
{
|
||||
resultPortal.Set(index, componentRangePortal.Get(subComponent));
|
||||
++index;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<T, ST3> thirdArray = input.GetThirdArray();
|
||||
componentRangeArray = vtkm::cont::internal::ArrayRangeComputeImpl<ST3>{}(thirdArray, device);
|
||||
numSubComponents = componentRangeArray.GetNumberOfValues();
|
||||
if (numSubComponents > 1)
|
||||
{
|
||||
result.Allocate(result.GetNumberOfValues() + numSubComponents - 1, vtkm::CopyFlag::On);
|
||||
resultPortal = result.WritePortal();
|
||||
}
|
||||
componentRangePortal = componentRangeArray.ReadPortal();
|
||||
for (vtkm::IdComponent subComponent = 0; subComponent < numSubComponents; ++subComponent)
|
||||
{
|
||||
resultPortal.Set(index, componentRangePortal.Get(subComponent));
|
||||
++index;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -12,8 +12,11 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/VecFlat.h>
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -106,8 +109,18 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagConstant>
|
||||
template <typename T>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>& input,
|
||||
vtkm::cont::DeviceAdapterId) const
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId devId) const
|
||||
{
|
||||
bool allMasked = false;
|
||||
if (maskArray.GetNumberOfValues() != 0)
|
||||
{
|
||||
// Find if there is atleast one value that is not masked
|
||||
auto ids = GetFirstAndLastUnmaskedIndices(maskArray, devId);
|
||||
allMasked = (ids[1] < ids[0]);
|
||||
}
|
||||
|
||||
auto value = vtkm::make_VecFlat(input.ReadPortal().Get(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
@ -115,12 +128,51 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagConstant>
|
||||
auto resultPortal = result.WritePortal();
|
||||
for (vtkm::IdComponent index = 0; index < value.GetNumberOfComponents(); ++index)
|
||||
{
|
||||
resultPortal.Set(index, vtkm::Range{ value[index], value[index] });
|
||||
auto comp = static_cast<vtkm::Float64>(value[index]);
|
||||
if (allMasked || (computeFiniteRange && !vtkm::IsFinite(comp)))
|
||||
{
|
||||
resultPortal.Set(index, vtkm::Range{});
|
||||
}
|
||||
else
|
||||
{
|
||||
resultPortal.Set(index, vtkm::Range{ comp, comp });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeMagnitudeImpl;
|
||||
|
||||
template <>
|
||||
struct VTKM_CONT_EXPORT ArrayRangeComputeMagnitudeImpl<vtkm::cont::StorageTagConstant>
|
||||
{
|
||||
template <typename T>
|
||||
VTKM_CONT vtkm::Range operator()(
|
||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId devId) const
|
||||
{
|
||||
if (maskArray.GetNumberOfValues() != 0)
|
||||
{
|
||||
// Find if there is atleast one value that is not masked
|
||||
auto ids = GetFirstAndLastUnmaskedIndices(maskArray, devId);
|
||||
if (ids[1] < ids[0])
|
||||
{
|
||||
return vtkm::Range{};
|
||||
}
|
||||
}
|
||||
|
||||
auto value = input.ReadPortal().Get(0);
|
||||
vtkm::Float64 rangeValue = vtkm::Magnitude(vtkm::make_VecFlat(value));
|
||||
return (computeFiniteRange && !vtkm::IsFinite(rangeValue))
|
||||
? vtkm::Range{}
|
||||
: vtkm::Range{ rangeValue, rangeValue };
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
|
@ -12,8 +12,11 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/TypeTraits.h>
|
||||
#include <vtkm/VecFlat.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -156,33 +159,45 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagCounting>
|
||||
template <typename T>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagCounting>& input,
|
||||
vtkm::cont::DeviceAdapterId) const
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool vtkmNotUsed(computeFiniteRange), // assume array produces only finite values
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
using Traits = vtkm::VecTraits<vtkm::VecFlat<T>>;
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(Traits::NUM_COMPONENTS);
|
||||
|
||||
if (input.GetNumberOfValues() <= 0)
|
||||
{
|
||||
result.Fill(vtkm::Range{});
|
||||
return result;
|
||||
}
|
||||
|
||||
vtkm::Id2 firstAndLast{ 0, input.GetNumberOfValues() - 1 };
|
||||
if (maskArray.GetNumberOfValues() > 0)
|
||||
{
|
||||
firstAndLast = GetFirstAndLastUnmaskedIndices(maskArray, device);
|
||||
}
|
||||
|
||||
if (firstAndLast[1] < firstAndLast[0])
|
||||
{
|
||||
result.Fill(vtkm::Range{});
|
||||
return result;
|
||||
}
|
||||
|
||||
auto portal = result.WritePortal();
|
||||
if (portal.GetNumberOfValues() > 0)
|
||||
// assume the values to be finite
|
||||
auto first = make_VecFlat(input.ReadPortal().Get(firstAndLast[0]));
|
||||
auto last = make_VecFlat(input.ReadPortal().Get(firstAndLast[1]));
|
||||
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::NUM_COMPONENTS; ++cIndex)
|
||||
{
|
||||
T first = input.ReadPortal().Get(0);
|
||||
T last = input.ReadPortal().Get(input.GetNumberOfValues() - 1);
|
||||
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::NUM_COMPONENTS; ++cIndex)
|
||||
{
|
||||
auto firstComponent = Traits::GetComponent(first, cIndex);
|
||||
auto lastComponent = Traits::GetComponent(last, cIndex);
|
||||
portal.Set(cIndex,
|
||||
vtkm::Range(vtkm::Min(firstComponent, lastComponent),
|
||||
vtkm::Max(firstComponent, lastComponent)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Array is empty
|
||||
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::NUM_COMPONENTS; ++cIndex)
|
||||
{
|
||||
portal.Set(cIndex, vtkm::Range{});
|
||||
}
|
||||
auto firstComponent = Traits::GetComponent(first, cIndex);
|
||||
auto lastComponent = Traits::GetComponent(last, cIndex);
|
||||
portal.Set(cIndex,
|
||||
vtkm::Range(vtkm::Min(firstComponent, lastComponent),
|
||||
vtkm::Max(firstComponent, lastComponent)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#include <vtkmstd/integer_sequence.h>
|
||||
|
||||
|
||||
#include <array>
|
||||
#include <numeric>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
51
vtkm/cont/ArrayHandleIndex.cxx
Normal file
51
vtkm/cont/ArrayHandleIndex.cxx
Normal file
@ -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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range>
|
||||
ArrayRangeComputeImpl<vtkm::cont::StorageTagIndex>::operator()(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool vtkmNotUsed(computeFiniteRange), // assume array produces only finite values
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
vtkm::Range range{};
|
||||
|
||||
if (input.GetNumberOfValues() > 0)
|
||||
{
|
||||
vtkm::Id2 firstAndLast{ 0, input.GetNumberOfValues() - 1 };
|
||||
if (maskArray.GetNumberOfValues() > 0)
|
||||
{
|
||||
firstAndLast = vtkm::cont::internal::GetFirstAndLastUnmaskedIndices(maskArray, device);
|
||||
}
|
||||
if (firstAndLast[0] < firstAndLast[1])
|
||||
{
|
||||
range = vtkm::Range(firstAndLast[0], firstAndLast[1]);
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(1);
|
||||
result.WritePortal().Set(0, range);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // vtkm::cont::internal
|
@ -84,12 +84,26 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagIndex>
|
||||
{
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||
vtkm::cont::DeviceAdapterId) const
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeMagnitudeImpl;
|
||||
|
||||
template <>
|
||||
struct VTKM_CONT_EXPORT ArrayRangeComputeMagnitudeImpl<vtkm::cont::StorageTagIndex>
|
||||
{
|
||||
VTKM_CONT vtkm::Range operator()(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(1);
|
||||
result.WritePortal().Set(0, vtkm::Range(0, input.GetNumberOfValues() - 1));
|
||||
return result;
|
||||
auto rangeAH = ArrayRangeComputeImpl<vtkm::cont::StorageTagIndex>{}(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
return rangeAH.ReadPortal().Get(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -13,8 +13,11 @@
|
||||
#include <vtkm/cont/ArrayExtractComponent.h>
|
||||
#include <vtkm/cont/ArrayHandleMultiplexer.h>
|
||||
#include <vtkm/cont/ArrayHandleStride.h>
|
||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||
#include <vtkm/cont/DeviceAdapterTag.h>
|
||||
|
||||
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||
|
||||
#include <vtkm/internal/ArrayPortalValueReference.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -648,6 +651,110 @@ struct ArrayExtractComponentImpl<vtkm::cont::internal::StorageTagRecombineVec>
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl;
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeMagnitudeImpl;
|
||||
|
||||
template <typename T, typename S>
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImplCaller(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
return vtkm::cont::internal::ArrayRangeComputeImpl<S>{}(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
inline vtkm::Range ArrayRangeComputeMagnitudeImplCaller(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
return vtkm::cont::internal::ArrayRangeComputeMagnitudeImpl<S>{}(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::internal::StorageTagRecombineVec>
|
||||
{
|
||||
template <typename RecombineVecType>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandle<RecombineVecType, vtkm::cont::internal::StorageTagRecombineVec>&
|
||||
input_,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
auto input =
|
||||
static_cast<vtkm::cont::ArrayHandleRecombineVec<typename RecombineVecType::ComponentType>>(
|
||||
input_);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(input.GetNumberOfComponents());
|
||||
|
||||
if (input.GetNumberOfValues() < 1)
|
||||
{
|
||||
result.Fill(vtkm::Range{});
|
||||
return result;
|
||||
}
|
||||
|
||||
auto resultPortal = result.WritePortal();
|
||||
for (vtkm::IdComponent i = 0; i < input.GetNumberOfComponents(); ++i)
|
||||
{
|
||||
auto rangeAH = ArrayRangeComputeImplCaller(
|
||||
input.GetComponentArray(i), maskArray, computeFiniteRange, device);
|
||||
resultPortal.Set(i, rangeAH.ReadPortal().Get(0));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
struct ArrayValueIsNested;
|
||||
|
||||
template <typename RecombineVecType>
|
||||
struct ArrayValueIsNested<
|
||||
vtkm::cont::ArrayHandle<RecombineVecType, vtkm::cont::internal::StorageTagRecombineVec>>
|
||||
{
|
||||
static constexpr bool Value = false;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct VTKM_CONT_EXPORT ArrayRangeComputeMagnitudeImpl<vtkm::cont::internal::StorageTagRecombineVec>
|
||||
{
|
||||
template <typename RecombineVecType>
|
||||
VTKM_CONT vtkm::Range operator()(
|
||||
const vtkm::cont::ArrayHandle<RecombineVecType, vtkm::cont::internal::StorageTagRecombineVec>&
|
||||
input_,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
auto input =
|
||||
static_cast<vtkm::cont::ArrayHandleRecombineVec<typename RecombineVecType::ComponentType>>(
|
||||
input_);
|
||||
|
||||
if (input.GetNumberOfValues() < 1)
|
||||
{
|
||||
return vtkm::Range{};
|
||||
}
|
||||
if (input.GetNumberOfComponents() == 1)
|
||||
{
|
||||
return ArrayRangeComputeMagnitudeImplCaller(
|
||||
input.GetComponentArray(0), maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
return ArrayRangeComputeMagnitudeGeneric(input_, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ struct TransformFunctorManager
|
||||
}
|
||||
|
||||
template <typename ValueType>
|
||||
using TransformedValueType = decltype(std::declval<FunctorType>()(ValueType{}));
|
||||
using TransformedValueType = decltype(std::declval<FunctorType>()(std::declval<ValueType>()));
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType,
|
||||
|
@ -10,6 +10,10 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
|
||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
@ -89,8 +93,16 @@ ArrayExtractComponentImpl<vtkm::cont::StorageTagUniformPoints>::operator()(
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range>
|
||||
ArrayRangeComputeImpl<vtkm::cont::StorageTagUniformPoints>::operator()(
|
||||
const vtkm::cont::ArrayHandleUniformPointCoordinates& input,
|
||||
vtkm::cont::DeviceAdapterId vtkmNotUsed(device)) const
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
if (maskArray.GetNumberOfValues() != 0)
|
||||
{
|
||||
return vtkm::cont::internal::ArrayRangeComputeGeneric(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
vtkm::internal::ArrayPortalUniformPointCoordinates portal = input.ReadPortal();
|
||||
|
||||
// In this portal we know that the min value is the first entry and the
|
||||
|
@ -88,6 +88,8 @@ struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagUniformPoint
|
||||
{
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandleUniformPointCoordinates& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const;
|
||||
};
|
||||
|
||||
|
@ -8,13 +8,13 @@
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||
|
||||
#include <vtkm/TypeList.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandleBasic.h>
|
||||
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
@ -42,50 +42,39 @@ using AllVec = vtkm::ListAppend<AllVecOfSize<2>, AllVecOfSize<3>, AllVecOfSize<4
|
||||
|
||||
using AllTypes = vtkm::ListAppend<AllScalars, AllVec>;
|
||||
|
||||
struct ComputeRangeFunctor
|
||||
{
|
||||
// Used with UnknownArrayHandle::CastAndCallForTypes
|
||||
template <typename T, typename S>
|
||||
void operator()(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::ArrayHandle<vtkm::Range>& ranges) const
|
||||
{
|
||||
ranges = vtkm::cont::ArrayRangeComputeTemplate(array, device);
|
||||
using CartesianProductStorage = vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
||||
vtkm::cont::StorageTagBasic,
|
||||
vtkm::cont::StorageTagBasic>;
|
||||
|
||||
using StorageTagsList = vtkm::List<vtkm::cont::StorageTagBasic,
|
||||
vtkm::cont::StorageTagSOA,
|
||||
vtkm::cont::StorageTagXGCCoordinates,
|
||||
vtkm::cont::StorageTagUniformPoints,
|
||||
CartesianProductStorage,
|
||||
vtkm::cont::StorageTagConstant,
|
||||
vtkm::cont::StorageTagCounting,
|
||||
vtkm::cont::StorageTagIndex>;
|
||||
|
||||
template <typename StorageTag>
|
||||
struct StorageTagToValueTypesMap;
|
||||
|
||||
#define MAP_STORAGE_TAG_VALUE_TYPES(StorageTag, ValueTypesList) \
|
||||
template <> \
|
||||
struct StorageTagToValueTypesMap<StorageTag> \
|
||||
{ \
|
||||
using TypeList = ValueTypesList; \
|
||||
}
|
||||
|
||||
// Used with vtkm::ListForEach to get components
|
||||
template <typename T>
|
||||
void operator()(T,
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::ArrayHandle<vtkm::Range>& ranges,
|
||||
bool& success) const
|
||||
{
|
||||
if (!success && array.IsBaseComponentType<T>())
|
||||
{
|
||||
vtkm::IdComponent numComponents = array.GetNumberOfComponentsFlat();
|
||||
ranges.Allocate(numComponents);
|
||||
auto rangePortal = ranges.WritePortal();
|
||||
for (vtkm::IdComponent componentI = 0; componentI < numComponents; ++componentI)
|
||||
{
|
||||
vtkm::cont::ArrayHandleStride<T> componentArray = array.ExtractComponent<T>(componentI);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> componentRange =
|
||||
vtkm::cont::ArrayRangeComputeTemplate(componentArray, device);
|
||||
rangePortal.Set(componentI, componentRange.ReadPortal().Get(0));
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagBasic, AllTypes);
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagSOA, AllVec);
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagXGCCoordinates, vtkm::TypeListFieldVec3);
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagUniformPoints, vtkm::List<vtkm::Vec3f>);
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(CartesianProductStorage, vtkm::TypeListFieldVec3);
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagConstant, AllTypes);
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagCounting, AllTypes);
|
||||
MAP_STORAGE_TAG_VALUE_TYPES(vtkm::cont::StorageTagIndex, vtkm::List<vtkm::Id>);
|
||||
|
||||
template <typename TList, typename Storage>
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ComputeForStorage(const vtkm::cont::UnknownArrayHandle& array,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
||||
array.CastAndCallForTypes<TList, vtkm::List<Storage>>(ComputeRangeFunctor{}, device, ranges);
|
||||
return ranges;
|
||||
}
|
||||
#undef MAP_STORAGE_TAG_VALUE_TYPES
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@ -105,49 +94,44 @@ void ThrowArrayRangeComputeFailed()
|
||||
} // namespace internal
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::UnknownArrayHandle& array,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
// First, try fast-paths of precompiled array types common(ish) in fields.
|
||||
return ArrayRangeCompute(
|
||||
array, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
// First, try (potentially fast-paths) for common(ish) array types.
|
||||
try
|
||||
{
|
||||
if (array.IsStorageType<vtkm::cont::StorageTagBasic>())
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
||||
|
||||
auto computeForArrayHandle = [&](const auto& input) {
|
||||
ranges = vtkm::cont::ArrayRangeComputeTemplate(input, maskArray, computeFiniteRange, device);
|
||||
};
|
||||
|
||||
bool success = false;
|
||||
auto computeForStorage = [&](auto storageTag) {
|
||||
using STag = decltype(storageTag);
|
||||
using VTypes = typename StorageTagToValueTypesMap<STag>::TypeList;
|
||||
if (array.IsStorageType<STag>())
|
||||
{
|
||||
array.CastAndCallForTypes<VTypes, vtkm::List<STag>>(computeForArrayHandle);
|
||||
success = true;
|
||||
}
|
||||
};
|
||||
|
||||
vtkm::ListForEach(computeForStorage, StorageTagsList{});
|
||||
|
||||
if (success)
|
||||
{
|
||||
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagBasic>(array, device);
|
||||
}
|
||||
if (array.IsStorageType<vtkm::cont::StorageTagSOA>())
|
||||
{
|
||||
return ComputeForStorage<AllVec, vtkm::cont::StorageTagSOA>(array, device);
|
||||
}
|
||||
if (array.IsStorageType<vtkm::cont::StorageTagXGCCoordinates>())
|
||||
{
|
||||
return ComputeForStorage<vtkm::TypeListFieldVec3, vtkm::cont::StorageTagXGCCoordinates>(
|
||||
array, device);
|
||||
}
|
||||
if (array.IsStorageType<vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag>())
|
||||
{
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates uniformPoints;
|
||||
array.AsArrayHandle(uniformPoints);
|
||||
return vtkm::cont::ArrayRangeComputeTemplate(uniformPoints, device);
|
||||
}
|
||||
using CartesianProductStorage =
|
||||
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
||||
vtkm::cont::StorageTagBasic,
|
||||
vtkm::cont::StorageTagBasic>;
|
||||
if (array.IsStorageType<CartesianProductStorage>())
|
||||
{
|
||||
return ComputeForStorage<vtkm::TypeListFieldVec3, CartesianProductStorage>(array, device);
|
||||
}
|
||||
if (array.IsStorageType<vtkm::cont::StorageTagConstant>())
|
||||
{
|
||||
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagConstant>(array, device);
|
||||
}
|
||||
if (array.IsStorageType<vtkm::cont::StorageTagCounting>())
|
||||
{
|
||||
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagCounting>(array, device);
|
||||
}
|
||||
if (array.IsStorageType<vtkm::cont::StorageTagIndex>())
|
||||
{
|
||||
return ArrayRangeComputeTemplate(array.AsArrayHandle<vtkm::cont::ArrayHandleIndex>(), device);
|
||||
return ranges;
|
||||
}
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadType&)
|
||||
@ -155,11 +139,104 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::Unknown
|
||||
// If a cast/call failed, try falling back to a more general implementation.
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
||||
// fallback
|
||||
bool success = false;
|
||||
vtkm::ListForEach(ComputeRangeFunctor{}, AllScalars{}, array, device, ranges, success);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
|
||||
auto computeForExtractComponent = [&](auto valueTypeObj) {
|
||||
using VT = decltype(valueTypeObj);
|
||||
if (!success && array.IsBaseComponentType<VT>())
|
||||
{
|
||||
vtkm::IdComponent numComponents = array.GetNumberOfComponentsFlat();
|
||||
ranges.Allocate(numComponents);
|
||||
auto rangePortal = ranges.WritePortal();
|
||||
for (vtkm::IdComponent i = 0; i < numComponents; ++i)
|
||||
{
|
||||
auto componentArray = array.ExtractComponent<VT>(i);
|
||||
auto componentRange = vtkm::cont::ArrayRangeComputeTemplate(
|
||||
componentArray, maskArray, computeFiniteRange, device);
|
||||
rangePortal.Set(i, componentRange.ReadPortal().Get(0));
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
};
|
||||
|
||||
vtkm::ListForEach(computeForExtractComponent, AllScalars{});
|
||||
if (!success)
|
||||
{
|
||||
internal::ThrowArrayRangeComputeFailed();
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
vtkm::Range ArrayRangeComputeMagnitude(const vtkm::cont::UnknownArrayHandle& array,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
return ArrayRangeComputeMagnitude(
|
||||
array, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
vtkm::Range ArrayRangeComputeMagnitude(const vtkm::cont::UnknownArrayHandle& array,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
// First, try (potentially fast-paths) for common(ish) array types.
|
||||
try
|
||||
{
|
||||
vtkm::Range range;
|
||||
|
||||
auto computeForArrayHandle = [&](const auto& input) {
|
||||
range = vtkm::cont::ArrayRangeComputeMagnitudeTemplate(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
};
|
||||
|
||||
bool success = false;
|
||||
auto computeForStorage = [&](auto storageTag) {
|
||||
using STag = decltype(storageTag);
|
||||
using VTypes = typename StorageTagToValueTypesMap<STag>::TypeList;
|
||||
if (array.IsStorageType<STag>())
|
||||
{
|
||||
array.CastAndCallForTypes<VTypes, vtkm::List<STag>>(computeForArrayHandle);
|
||||
success = true;
|
||||
}
|
||||
};
|
||||
|
||||
vtkm::ListForEach(computeForStorage, StorageTagsList{});
|
||||
|
||||
if (success)
|
||||
{
|
||||
return range;
|
||||
}
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadType&)
|
||||
{
|
||||
// If a cast/call failed, try falling back to a more general implementation.
|
||||
}
|
||||
|
||||
// fallback
|
||||
bool success = false;
|
||||
vtkm::Range range;
|
||||
auto computeForExtractArrayFromComponents = [&](auto valueTypeObj) {
|
||||
using VT = decltype(valueTypeObj);
|
||||
if (!success && array.IsBaseComponentType<VT>())
|
||||
{
|
||||
auto extractedArray = array.ExtractArrayFromComponents<VT>();
|
||||
range = vtkm::cont::ArrayRangeComputeMagnitudeTemplate(
|
||||
extractedArray, maskArray, computeFiniteRange, device);
|
||||
success = true;
|
||||
}
|
||||
};
|
||||
|
||||
vtkm::ListForEach(computeForExtractArrayFromComponents, AllScalars{});
|
||||
if (!success)
|
||||
{
|
||||
internal::ThrowArrayRangeComputeFailed();
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -11,18 +11,8 @@
|
||||
#define vtk_m_cont_ArrayRangeCompute_h
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/ArrayHandleSOA.h>
|
||||
#include <vtkm/cont/ArrayHandleStride.h>
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
|
||||
#include <vtkm/cont/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/UnknownArrayHandle.h>
|
||||
|
||||
@ -31,30 +21,116 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
/// @{
|
||||
/// \brief Compute the range of the data in an array handle.
|
||||
///
|
||||
/// Given an `ArrayHandle`, this function computes the range (min and max) of
|
||||
/// the values in the array. For arrays containing Vec values, the range is
|
||||
/// computed for each component.
|
||||
/// computed for each component, and in the case of nested Vecs, ranges are computed
|
||||
/// for each of the leaf components.
|
||||
///
|
||||
/// This method optionally takes a `vtkm::cont::DeviceAdapterId` to control which
|
||||
/// devices to try.
|
||||
/// \param array The input array as a `vtkm::cont::UnknownArrayHandle`.
|
||||
/// \param maskArray An array handle of type `vtkm::cont::ArrayHandle<vtkm::UInt8>`.
|
||||
/// This array should have the same number of elements as the input array
|
||||
/// with each value representing the masking status of the corresponding
|
||||
/// value in the input array (masked if 0 else unmasked). Ignored if empty.
|
||||
/// \param computeFiniteRange Optional boolean parameter to specify if non-finite values in the
|
||||
/// array should be ignored to compute the finite range of
|
||||
/// the array. For Vec types, individual component values
|
||||
/// are considered independantly.
|
||||
/// \param device This optional parameter can be used to specify a device to run the
|
||||
/// range computation on. The default value is `vtkm::cont::DeviceAdapterTagAny{}`.
|
||||
///
|
||||
/// The result is returned in an `ArrayHandle` of `Range` objects. There is
|
||||
/// \return The result is returned in an `ArrayHandle` of `Range` objects. There is
|
||||
/// one value in the returned array for every component of the input's value
|
||||
/// type.
|
||||
/// type. For nested Vecs the results are stored in depth-first order.
|
||||
///
|
||||
/// Note that the ArrayRangeCompute.h header file contains only precompiled overloads
|
||||
/// of ArrayRangeCompute. This is so that ArrayRangeCompute.h can be included in
|
||||
/// code that does not use a device compiler. If you need to compute array ranges
|
||||
/// for arbitrary `ArrayHandle`s not in this precompiled list, you need to use
|
||||
/// `ArrayRangeComputeTemplate` (declared in `ArrayRangeComputeTemplate`), which
|
||||
/// will compile for any `ArrayHandle` type not already handled.
|
||||
/// \note `ArrayRangeCompute` takes an UnknownArrayHandle as the input.
|
||||
/// The implementation uses precompiled and specicialized code for several of the
|
||||
/// most commonly used value and storage types, with a fallback for other cases.
|
||||
/// This is so that ArrayRangeCompute.h can be included in code that does not use a
|
||||
/// device compiler. This should be sufficient for most cases, but if you need to
|
||||
/// compute the range for an array type that is not explicitly handled by
|
||||
/// `ArrayRangeCompute` and the fallback code is not performant, use the
|
||||
/// templated version `ArrayRangeComputeTemplate`. Specializations can be
|
||||
/// implemented by specializing the template class `ArrayRangeComputeImpl`.
|
||||
/// Please refer to ArrayRangeComputeTemplate.h for details
|
||||
///
|
||||
/// \sa ArrayRangeComputeTemplate
|
||||
///
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
return ArrayRangeCompute(array, false, device);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// @{
|
||||
/// \brief Compute the range of the magnitude of the Vec data in an array handle.
|
||||
///
|
||||
/// Given an `ArrayHandle`, this function computes the range (min and max) of
|
||||
/// the magnitude of the values in the array.
|
||||
///
|
||||
/// \param array The input array as a `vtkm::cont::UnknownArrayHandle`.
|
||||
/// \param maskArray An array handle of type `vtkm::cont::ArrayHandle<vtkm::UInt8>`.
|
||||
/// This array should have the same number of elements as the input array
|
||||
/// with each value representing the masking status of the corresponding
|
||||
/// value in the input array (masked if 0 else unmasked). Ignored if empty.
|
||||
/// \param computeFiniteRange Optional boolean value to specify if non-finite values in the
|
||||
/// array should be ignored to compute the finite range of
|
||||
/// the array. A Vec with any non-finite component will be
|
||||
/// ignored.
|
||||
/// \param device This optional parameter can be used to specify a device to run the
|
||||
/// range computation on. The default value is `vtkm::cont::DeviceAdapterTagAny{}`.
|
||||
///
|
||||
/// \return The result is returned in a single `Range` objects.
|
||||
///
|
||||
/// \note `ArrayRangeComputeMagnitude` takes an UnknownArrayHandle as the input.
|
||||
/// The implementation uses precompiled and specicialized code for several of the
|
||||
/// most commonly used value and storage types, with a fallback for other cases.
|
||||
/// This is so that ArrayRangeCompute.h can be included in code that does not use a
|
||||
/// device compiler. This should be sufficient for most cases, but if you need to
|
||||
/// compute the range for an array type that is not explicitly handled by
|
||||
/// `ArrayRangeComputeMagnitude` and the fallback code is not performant, use the
|
||||
/// templated version `ArrayRangeComputeMagnitudeTemplate`. Specializations can be
|
||||
/// implemented by specializing the template class `ArrayRangeComputeMagnitudeImpl`.
|
||||
/// Please refer to ArrayRangeComputeTemplate.h for details
|
||||
///
|
||||
/// \sa ArrayRangeComputeMagnitudeTemplate
|
||||
///
|
||||
VTKM_CONT_EXPORT vtkm::Range ArrayRangeComputeMagnitude(
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::Range ArrayRangeComputeMagnitude(
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||
|
||||
inline vtkm::Range ArrayRangeComputeMagnitude(const vtkm::cont::UnknownArrayHandle& array,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
return ArrayRangeComputeMagnitude(array, false, device);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
|
@ -10,257 +10,531 @@
|
||||
#ifndef vtk_m_cont_ArrayRangeComputeTemplate_h
|
||||
#define vtk_m_cont_ArrayRangeComputeTemplate_h
|
||||
|
||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleDecorator.h>
|
||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||
#include <vtkm/cont/internal/ArrayRangeComputeUtils.h>
|
||||
|
||||
#include <vtkm/BinaryOperators.h>
|
||||
#include <vtkm/Deprecated.h>
|
||||
#include <vtkm/VecFlat.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
#include <vtkm/VectorAnalysis.h>
|
||||
|
||||
#include <vtkm/internal/Instantiations.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct ArrayRangeComputeFunctor
|
||||
{
|
||||
template <typename Device, typename T, typename S>
|
||||
VTKM_CONT bool operator()(Device,
|
||||
const vtkm::cont::ArrayHandle<T, S>& handle,
|
||||
const vtkm::Vec<T, 2>& initialValue,
|
||||
vtkm::Vec<T, 2>& result) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<Device>;
|
||||
result = Algorithm::Reduce(handle, initialValue, vtkm::MinAndMax<T>());
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
struct ComputeRangeOptionsDecorator
|
||||
{
|
||||
bool IgnoreInf = false;
|
||||
|
||||
template <typename SrcPortal, typename MaskPortal>
|
||||
struct Functor
|
||||
{
|
||||
SrcPortal Src;
|
||||
MaskPortal Mask;
|
||||
bool IgnoreInf;
|
||||
|
||||
using InValueType = typename SrcPortal::ValueType;
|
||||
using InVecTraits = vtkm::VecTraits<InValueType>;
|
||||
using ResultType = vtkm::Vec<vtkm::Vec<vtkm::Float64, InVecTraits::NUM_COMPONENTS>, 2>;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ResultType operator()(vtkm::Id idx) const
|
||||
{
|
||||
if ((this->Mask.GetNumberOfValues() != 0) && (this->Mask.Get(idx) == 0))
|
||||
{
|
||||
return { { vtkm::Range{}.Min }, { vtkm::Range{}.Max } };
|
||||
}
|
||||
|
||||
const auto& inVal = this->Src.Get(idx);
|
||||
ResultType outVal;
|
||||
for (vtkm::IdComponent i = 0; i < InVecTraits::NUM_COMPONENTS; ++i)
|
||||
{
|
||||
auto val = static_cast<vtkm::Float64>(InVecTraits::GetComponent(inVal, i));
|
||||
if (vtkm::IsNan(val) || (this->IgnoreInf && !vtkm::IsFinite(val)))
|
||||
{
|
||||
outVal[0][i] = vtkm::Range{}.Min;
|
||||
outVal[1][i] = vtkm::Range{}.Max;
|
||||
}
|
||||
else
|
||||
{
|
||||
outVal[0][i] = outVal[1][i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
return outVal;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SrcPortal, typename GhostPortal>
|
||||
Functor<SrcPortal, GhostPortal> CreateFunctor(const SrcPortal& sp, const GhostPortal& gp) const
|
||||
{
|
||||
return { sp, gp, this->IgnoreInf };
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
struct ArrayValueIsNested
|
||||
{
|
||||
static constexpr bool Value =
|
||||
!vtkm::internal::IsFlatVec<typename ArrayHandleType::ValueType>::value;
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType, bool IsNested = ArrayValueIsNested<ArrayHandleType>::Value>
|
||||
struct NestedToFlat;
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
struct NestedToFlat<ArrayHandleType, true>
|
||||
{
|
||||
static auto Transform(const ArrayHandleType& in)
|
||||
{
|
||||
return vtkm::cont::ArrayHandleCast<vtkm::VecFlat<typename ArrayHandleType::ValueType>,
|
||||
ArrayHandleType>(in);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
struct NestedToFlat<ArrayHandleType, false>
|
||||
{
|
||||
static auto Transform(const ArrayHandleType& in) { return in; }
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
inline auto NestedToFlatTransform(const ArrayHandleType& input)
|
||||
{
|
||||
return NestedToFlat<ArrayHandleType>::Transform(input);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/// \brief A generic implementation of `ArrayRangeCompute`. This is the implementation used
|
||||
/// when `ArrayRangeComputeImpl` is not specialized.
|
||||
///
|
||||
template <typename T, typename S>
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeGeneric(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ArrayRangeCompute");
|
||||
|
||||
using VecTraits = vtkm::VecTraits<T>;
|
||||
using CT = typename VecTraits::ComponentType;
|
||||
//We want to minimize the amount of code that we do in try execute as
|
||||
//it is repeated for each
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> range;
|
||||
range.Allocate(VecTraits::NUM_COMPONENTS);
|
||||
|
||||
//We want to minimize the amount of code that we do in try execute as
|
||||
//it is repeated for each
|
||||
if (input.GetNumberOfValues() < 1)
|
||||
{
|
||||
auto portal = range.WritePortal();
|
||||
for (vtkm::IdComponent i = 0; i < VecTraits::NUM_COMPONENTS; ++i)
|
||||
{
|
||||
portal.Set(i, vtkm::Range());
|
||||
}
|
||||
range.Fill(vtkm::Range{});
|
||||
}
|
||||
else
|
||||
{
|
||||
//We used the limits, so that we don't need to sync the array handle
|
||||
//
|
||||
vtkm::Vec<T, 2> result;
|
||||
vtkm::Vec<T, 2> initial;
|
||||
initial[0] = T(std::numeric_limits<CT>::max());
|
||||
initial[1] = T(std::numeric_limits<CT>::lowest());
|
||||
// if input is an array of nested vectors, transform them to `VecFlat` using ArrayHandleCast
|
||||
auto flattened = NestedToFlatTransform(input);
|
||||
ComputeRangeOptionsDecorator decorator{ computeFiniteRange };
|
||||
auto decorated =
|
||||
make_ArrayHandleDecorator(flattened.GetNumberOfValues(), decorator, flattened, maskArray);
|
||||
|
||||
const bool rangeComputed = vtkm::cont::TryExecuteOnDevice(
|
||||
device, vtkm::cont::detail::ArrayRangeComputeFunctor{}, input, initial, result);
|
||||
if (!rangeComputed)
|
||||
using ResultType = vtkm::Vec<vtkm::Vec<vtkm::Float64, VecTraits::NUM_COMPONENTS>, 2>;
|
||||
using MinAndMaxFunctor = vtkm::MinAndMax<typename ResultType::ComponentType>;
|
||||
ResultType identity{ { vtkm::Range{}.Min }, { vtkm::Range{}.Max } };
|
||||
|
||||
auto result = vtkm::cont::Algorithm::Reduce(device, decorated, identity, MinAndMaxFunctor{});
|
||||
|
||||
auto portal = range.WritePortal();
|
||||
for (vtkm::IdComponent i = 0; i < VecTraits::NUM_COMPONENTS; ++i)
|
||||
{
|
||||
ThrowArrayRangeComputeFailed();
|
||||
portal.Set(i, vtkm::Range(result[0][i], result[1][i]));
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
struct ScalarMagnitudeFunctor
|
||||
{
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT vtkm::Float64 operator()(const T& val) const
|
||||
{
|
||||
// spcilization of `vtkm::Magnitude` for scalars should avoid `sqrt` computation by using `abs`
|
||||
// instead
|
||||
return static_cast<vtkm::Float64>(vtkm::Magnitude(val));
|
||||
}
|
||||
};
|
||||
|
||||
struct MagnitudeSquareFunctor
|
||||
{
|
||||
template <typename T>
|
||||
VTKM_EXEC_CONT vtkm::Float64 operator()(const T& val) const
|
||||
{
|
||||
using VecTraits = vtkm::VecTraits<T>;
|
||||
vtkm::Float64 result = 0;
|
||||
for (vtkm::IdComponent i = 0; i < VecTraits::GetNumberOfComponents(val); ++i)
|
||||
{
|
||||
auto portal = range.WritePortal();
|
||||
for (vtkm::IdComponent i = 0; i < VecTraits::NUM_COMPONENTS; ++i)
|
||||
{
|
||||
portal.Set(i,
|
||||
vtkm::Range(VecTraits::GetComponent(result[0], i),
|
||||
VecTraits::GetComponent(result[1], i)));
|
||||
}
|
||||
auto comp = static_cast<vtkm::Float64>(VecTraits::GetComponent(val, i));
|
||||
result += comp * comp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
vtkm::Range ArrayRangeComputeMagnitudeGenericImpl(
|
||||
vtkm::VecTraitsTagSingleComponent,
|
||||
const ArrayHandleType& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
auto mag = vtkm::cont::make_ArrayHandleTransform(input, ScalarMagnitudeFunctor{});
|
||||
auto rangeAH = ArrayRangeComputeGeneric(mag, maskArray, computeFiniteRange, device);
|
||||
return rangeAH.ReadPortal().Get(0);
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
vtkm::Range ArrayRangeComputeMagnitudeGenericImpl(
|
||||
vtkm::VecTraitsTagMultipleComponents,
|
||||
const ArrayHandleType& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
auto magsqr = vtkm::cont::make_ArrayHandleTransform(input, MagnitudeSquareFunctor{});
|
||||
auto rangeAH = ArrayRangeComputeGeneric(magsqr, maskArray, computeFiniteRange, device);
|
||||
auto range = rangeAH.ReadPortal().Get(0);
|
||||
if (range.IsNonEmpty())
|
||||
{
|
||||
range.Min = vtkm::Sqrt(range.Min);
|
||||
range.Max = vtkm::Sqrt(range.Max);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
/// \brief A generic implementation of `ArrayRangeComputeMagnitude`. This is the implementation used
|
||||
/// when `ArrayRangeComputeMagnitudeImpl` is not specialized.
|
||||
///
|
||||
template <typename T, typename S>
|
||||
inline vtkm::Range ArrayRangeComputeMagnitudeGeneric(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "ArrayRangeComputeMagnitude");
|
||||
|
||||
using VecTraits = vtkm::VecTraits<T>;
|
||||
|
||||
//We want to minimize the amount of code that we do in try execute as
|
||||
//it is repeated for each
|
||||
if (input.GetNumberOfValues() < 1)
|
||||
{
|
||||
return vtkm::Range{};
|
||||
}
|
||||
|
||||
auto flattened = NestedToFlatTransform(input);
|
||||
return ArrayRangeComputeMagnitudeGenericImpl(
|
||||
typename VecTraits::HasMultipleComponents{}, flattened, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl
|
||||
{
|
||||
template <typename T>
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> operator()(const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
return vtkm::cont::internal::ArrayRangeComputeGeneric(input, device);
|
||||
return vtkm::cont::internal::ArrayRangeComputeGeneric(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeMagnitudeImpl
|
||||
{
|
||||
template <typename T>
|
||||
vtkm::Range operator()(const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
return vtkm::cont::internal::ArrayRangeComputeMagnitudeGeneric(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||
const ArrayHandleType& input,
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/// @{
|
||||
/// \brief Templated version of ArrayRangeCompute
|
||||
/// \sa ArrayRangeCompute
|
||||
///
|
||||
template <typename T, typename S>
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
return internal::ArrayRangeComputeImpl<typename ArrayHandleType::StorageTag>{}(input, device);
|
||||
return ArrayRangeComputeTemplate(
|
||||
input, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
VTKM_ASSERT(maskArray.GetNumberOfValues() == 0 ||
|
||||
maskArray.GetNumberOfValues() == input.GetNumberOfValues());
|
||||
return internal::ArrayRangeComputeImpl<S>{}(input, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
return ArrayRangeComputeTemplate(input, false, device);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// @{
|
||||
/// \brief Templated version of ArrayRangeComputeMagnitude
|
||||
/// \sa ArrayRangeComputeMagnitude
|
||||
///
|
||||
template <typename T, typename S>
|
||||
inline vtkm::Range ArrayRangeComputeMagnitudeTemplate(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
return ArrayRangeComputeMagnitudeTemplate(
|
||||
input, vtkm::cont::ArrayHandle<vtkm::UInt8>{}, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::Range ArrayRangeComputeMagnitudeTemplate(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool computeFiniteRange = false,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
VTKM_ASSERT(maskArray.GetNumberOfValues() == 0 ||
|
||||
maskArray.GetNumberOfValues() == input.GetNumberOfValues());
|
||||
return internal::ArrayRangeComputeMagnitudeImpl<S>{}(
|
||||
input, maskArray, computeFiniteRange, device);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
inline vtkm::Range ArrayRangeComputeMagnitudeTemplate(const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
return ArrayRangeComputeMagnitudeTemplate(input, false, device);
|
||||
}
|
||||
/// @}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_DEPRECATED(2.1, "Use precompiled ArrayRangeCompute or ArrayRangeComputeTemplate.")
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const ArrayHandleType& input,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
return ArrayRangeComputeTemplate(input, device);
|
||||
return ArrayRangeComputeTemplate(input, false, device);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(modifiers, ...) \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Int8, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Int16, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt16, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Int32, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt32, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Int64, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt64, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Float32, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Float64, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<bool, __VA_ARGS__>& input, vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<char, __VA_ARGS__>& input, vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<signed VTKM_UNUSED_INT_TYPE, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<unsigned VTKM_UNUSED_INT_TYPE, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_DCLR(...) \
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<__VA_ARGS__>&, \
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>&, \
|
||||
bool, \
|
||||
vtkm::cont::DeviceAdapterId)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(modifiers, N, ...) \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int8, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt8, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Int16, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt16, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Int32, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt32, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Int64, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<UInt64, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Float32, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<Float64, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<bool, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<char, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<signed VTKM_UNUSED_INT_TYPE, N>, __VA_ARGS__>& input, \
|
||||
vtkm::cont::DeviceAdapterId device); \
|
||||
modifiers vtkm::cont::ArrayHandle<vtkm::Range> vtkm::cont::ArrayRangeComputeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<unsigned VTKM_UNUSED_INT_TYPE, N>, __VA_ARGS__>& \
|
||||
input, \
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(...) \
|
||||
vtkm::Range vtkm::cont::ArrayRangeComputeMagnitudeTemplate( \
|
||||
const vtkm::cont::ArrayHandle<__VA_ARGS__>&, \
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>&, \
|
||||
bool, \
|
||||
vtkm::cont::DeviceAdapterId)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_INT_SCALARS(modifiers, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int8, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int8, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt8, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt8, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int16, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int16, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt16, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt16, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int32, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int32, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt32, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt32, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Int64, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Int64, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::UInt64, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::UInt64, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_SCALARS(modifiers, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Float32, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Float32, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Float64, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Float64, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_BOOL_SCALARS(modifiers, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(bool, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(bool, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_OTHER_SCALARS(modifiers, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(char, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(char, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(signed VTKM_UNUSED_INT_TYPE, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(signed VTKM_UNUSED_INT_TYPE, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(unsigned VTKM_UNUSED_INT_TYPE, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(unsigned VTKM_UNUSED_INT_TYPE, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(modifiers, ...) \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_INT_SCALARS(modifiers, __VA_ARGS__); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_SCALARS(modifiers, __VA_ARGS__); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_BOOL_SCALARS(modifiers, __VA_ARGS__); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_OTHER_SCALARS(modifiers, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(modifiers, N, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Int8, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int8, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt8, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt8, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Int16, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int16, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt16, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt16, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Int32, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int32, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt32, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt32, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Int64, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Int64, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::UInt64, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::UInt64, N>, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(modifiers, N, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Float32, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Float32, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<vtkm::Float64, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<vtkm::Float64, N>, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_BOOL_VECN(modifiers, N, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<bool, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<bool, N>, __VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(modifiers, N, ...) \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<char, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<char, N>, __VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<signed VTKM_UNUSED_INT_TYPE, N>, \
|
||||
__VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<signed VTKM_UNUSED_INT_TYPE, N>, \
|
||||
__VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_DCLR(vtkm::Vec<unsigned VTKM_UNUSED_INT_TYPE, N>, \
|
||||
__VA_ARGS__); \
|
||||
modifiers VTK_M_ARRAY_RANGE_COMPUTE_MAG_DCLR(vtkm::Vec<unsigned VTKM_UNUSED_INT_TYPE, N>, \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(modifiers, N, ...) \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(modifiers, N, __VA_ARGS__); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(modifiers, N, __VA_ARGS__); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_BOOL_VECN(modifiers, N, __VA_ARGS__); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(modifiers, N, __VA_ARGS__)
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
struct StorageTagSOA;
|
||||
|
||||
template <typename ST1, typename ST2, typename ST3>
|
||||
struct StorageTagCartesianProduct;
|
||||
|
||||
struct StorageTagConstant;
|
||||
|
||||
struct StorageTagCounting;
|
||||
|
||||
struct StorageTagXGCCoordinates;
|
||||
|
||||
struct StorageTagStride;
|
||||
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
vtkm::cont::StorageTagBasic);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
2,
|
||||
vtkm::cont::StorageTagBasic);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
vtkm::cont::StorageTagBasic);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
4,
|
||||
vtkm::cont::StorageTagBasic);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
2,
|
||||
vtkm::cont::StorageTagSOA);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
vtkm::cont::StorageTagSOA);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
4,
|
||||
vtkm::cont::StorageTagSOA);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(
|
||||
extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
||||
@ -268,24 +542,87 @@ VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(
|
||||
vtkm::cont::StorageTagBasic>);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
StorageTagXGCCoordinates);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
vtkm::cont::StorageTagConstant);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
2,
|
||||
vtkm::cont::StorageTagConstant);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
vtkm::cont::StorageTagConstant);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
4,
|
||||
vtkm::cont::StorageTagConstant);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_INT_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_OTHER_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
2,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
2,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
2,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
3,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_INT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
4,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_FLOAT_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
4,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_OTHER_VECN(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
4,
|
||||
vtkm::cont::StorageTagCounting);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_ALL_SCALARS(extern template VTKM_CONT_TEMPLATE_EXPORT,
|
||||
vtkm::cont::StorageTagStride);
|
||||
VTKM_INSTANTIATION_END
|
||||
|
||||
#endif //vtk_m_cont_ArrayRangeComputeTemplate_h
|
||||
|
22
vtkm/cont/ArrayRangeComputeTemplateInstantiationsIncludes.h
Normal file
22
vtkm/cont/ArrayRangeComputeTemplateInstantiationsIncludes.h
Normal file
@ -0,0 +1,22 @@
|
||||
//============================================================================
|
||||
// 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_ArrayRangeComputeTemplateInstantiationsIncludes_h
|
||||
#define vtk_m_cont_ArrayRangeComputeTemplateInstantiationsIncludes_h
|
||||
|
||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleRecombineVec.h>
|
||||
#include <vtkm/cont/ArrayHandleSOA.h>
|
||||
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
|
||||
|
||||
#endif // vtk_m_cont_ArrayRangeComputeTemplateInstantiationsIncludes_h
|
@ -51,6 +51,7 @@ set(headers
|
||||
ArrayPortalToIterators.h
|
||||
ArrayRangeCompute.h
|
||||
ArrayRangeComputeTemplate.h
|
||||
ArrayRangeComputeTemplateInstantiationsIncludes.h
|
||||
AssignerPartitionedDataSet.h
|
||||
AtomicArray.h
|
||||
BitField.h
|
||||
@ -135,7 +136,6 @@ set(sources
|
||||
ArrayHandleBasic.cxx
|
||||
ArrayHandleSOA.cxx
|
||||
ArrayHandleStride.cxx
|
||||
ArrayHandleUniformPointCoordinates.cxx
|
||||
AssignerPartitionedDataSet.cxx
|
||||
BitField.cxx
|
||||
BoundsCompute.cxx
|
||||
@ -183,6 +183,8 @@ set(sources
|
||||
set(device_sources
|
||||
ArrayCopy.cxx
|
||||
ArrayGetValues.cxx
|
||||
ArrayHandleIndex.cxx
|
||||
ArrayHandleUniformPointCoordinates.cxx
|
||||
ArrayRangeCompute.cxx
|
||||
CellLocatorBoundingIntervalHierarchy.cxx
|
||||
CellLocatorUniformBins.cxx
|
||||
@ -193,6 +195,7 @@ set(device_sources
|
||||
ConvertNumComponentsToOffsets.cxx
|
||||
Field.cxx
|
||||
internal/ArrayCopyUnknown.cxx
|
||||
internal/ArrayRangeComputeUtils.cxx
|
||||
internal/Buffer.cxx
|
||||
internal/MapArrayPermutation.cxx
|
||||
MergePartitionedDataSet.cxx
|
||||
@ -268,6 +271,7 @@ vtkm_install_headers(vtkm/cont
|
||||
# compiles by breaking them up into smaller units.
|
||||
vtkm_add_instantiations(array_range_instantiations
|
||||
INSTANTIATIONS_FILE ArrayRangeComputeTemplate.h
|
||||
TEMPLATE_SOURCE ArrayRangeComputeTemplateInstantiationsIncludes.h
|
||||
)
|
||||
list(APPEND device_sources ${array_range_instantiations})
|
||||
|
||||
|
52
vtkm/cont/internal/ArrayRangeComputeUtils.cxx
Normal file
52
vtkm/cont/internal/ArrayRangeComputeUtils.cxx
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
//============================================================================
|
||||
// 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/ArrayRangeComputeUtils.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||
#include <vtkm/cont/ArrayHandleZip.h>
|
||||
|
||||
#include <vtkm/BinaryOperators.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct UnmaskedIndicesTransform
|
||||
{
|
||||
VTKM_EXEC vtkm::Id2 operator()(vtkm::Pair<vtkm::UInt8, vtkm::Id> in) const
|
||||
{
|
||||
if (in.first == 0)
|
||||
{
|
||||
return { std::numeric_limits<vtkm::Id>::max(), std::numeric_limits<vtkm::Id>::min() };
|
||||
}
|
||||
return { in.second };
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
vtkm::Id2 vtkm::cont::internal::GetFirstAndLastUnmaskedIndices(
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
vtkm::Id2 initialValue = { std::numeric_limits<vtkm::Id>::max(),
|
||||
std::numeric_limits<vtkm::Id>::min() };
|
||||
auto maskValsAndInds = vtkm::cont::make_ArrayHandleZip(
|
||||
maskArray, vtkm::cont::ArrayHandleIndex(maskArray.GetNumberOfValues()));
|
||||
auto unmaskedIndices =
|
||||
vtkm::cont::make_ArrayHandleTransform(maskValsAndInds, UnmaskedIndicesTransform{});
|
||||
return vtkm::cont::Algorithm::Reduce(
|
||||
device, unmaskedIndices, initialValue, vtkm::MinAndMax<vtkm::Id>());
|
||||
}
|
33
vtkm/cont/internal/ArrayRangeComputeUtils.h
Normal file
33
vtkm/cont/internal/ArrayRangeComputeUtils.h
Normal file
@ -0,0 +1,33 @@
|
||||
//============================================================================
|
||||
// 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_ArrayRangeComputeUtils_h
|
||||
#define vtk_m_cont_internal_ArrayRangeComputeUtils_h
|
||||
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::Id2 GetFirstAndLastUnmaskedIndices(
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||
|
||||
}
|
||||
}
|
||||
} // vtkm::cont::internal
|
||||
|
||||
#endif // vtk_m_cont_internal_ArrayRangeComputeUtils_h
|
@ -12,6 +12,7 @@ set(headers
|
||||
ArrayCopyUnknown.h
|
||||
ArrayHandleExecutionManager.h
|
||||
ArrayPortalFromIterators.h
|
||||
ArrayRangeComputeUtils.h
|
||||
ArrayTransfer.h
|
||||
Buffer.h
|
||||
CastInvalidValue.h
|
||||
|
@ -36,8 +36,10 @@ namespace
|
||||
constexpr vtkm::Id ARRAY_SIZE = 20;
|
||||
|
||||
template <typename T, typename S>
|
||||
void VerifyRange(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Range>& computedRangeArray)
|
||||
void VerifyRangeScalar(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Range>& computedRangeArray,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool finitesOnly)
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
|
||||
@ -46,40 +48,237 @@ void VerifyRange(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||
auto computedRangePortal = computedRangeArray.ReadPortal();
|
||||
|
||||
auto portal = array.ReadPortal();
|
||||
auto maskPortal = maskArray.ReadPortal();
|
||||
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
|
||||
{
|
||||
vtkm::Range computedRange = computedRangePortal.Get(component);
|
||||
vtkm::Range expectedRange;
|
||||
vtkm::Range expectedRange{};
|
||||
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); ++index)
|
||||
{
|
||||
T value = portal.Get(index);
|
||||
expectedRange.Include(Traits::GetComponent(value, component));
|
||||
if (maskPortal.GetNumberOfValues() != 0 && (maskPortal.Get(index) == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto value = static_cast<vtkm::Float64>(Traits::GetComponent(portal.Get(index), component));
|
||||
if (finitesOnly && !vtkm::IsFinite(value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
expectedRange.Include(value);
|
||||
}
|
||||
try
|
||||
{
|
||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Min));
|
||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Max));
|
||||
VTKM_TEST_ASSERT((!expectedRange.IsNonEmpty() && !computedRange.IsNonEmpty()) ||
|
||||
(test_equal(expectedRange, computedRange)));
|
||||
}
|
||||
catch (const vtkm::testing::Testing::TestFailure&)
|
||||
{
|
||||
std::cout << "Test array: \n";
|
||||
vtkm::cont::printSummary_ArrayHandle(array, std::cout, true);
|
||||
std::cout << "Mask array: \n";
|
||||
vtkm::cont::printSummary_ArrayHandle(maskArray, std::cout, true);
|
||||
std::cout << "Range type: " << (finitesOnly ? "Scalar, Finite" : "Scalar, NonFinite") << "\n";
|
||||
std::cout << "Computed range: \n";
|
||||
vtkm::cont::printSummary_ArrayHandle(computedRangeArray, std::cout, true);
|
||||
std::cout << "Expected range: " << expectedRange << ", component: " << component << "\n";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void VerifyRangeVector(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||
const vtkm::Range& computedRange,
|
||||
const vtkm::cont::ArrayHandle<vtkm::UInt8>& maskArray,
|
||||
bool finitesOnly)
|
||||
{
|
||||
auto portal = array.ReadPortal();
|
||||
auto maskPortal = maskArray.ReadPortal();
|
||||
vtkm::Range expectedRange{};
|
||||
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); ++index)
|
||||
{
|
||||
if (maskPortal.GetNumberOfValues() != 0 && (maskPortal.Get(index) == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto value = static_cast<vtkm::Float64>(vtkm::MagnitudeSquared(portal.Get(index)));
|
||||
if (finitesOnly && !vtkm::IsFinite(value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
expectedRange.Include(value);
|
||||
}
|
||||
|
||||
if (expectedRange.IsNonEmpty())
|
||||
{
|
||||
expectedRange.Min = vtkm::Sqrt(expectedRange.Min);
|
||||
expectedRange.Max = vtkm::Sqrt(expectedRange.Max);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Min));
|
||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Max));
|
||||
VTKM_TEST_ASSERT(test_equal(expectedRange, computedRange));
|
||||
VTKM_TEST_ASSERT((!expectedRange.IsNonEmpty() && !computedRange.IsNonEmpty()) ||
|
||||
(test_equal(expectedRange, computedRange)));
|
||||
}
|
||||
catch (const vtkm::testing::Testing::TestFailure&)
|
||||
{
|
||||
std::cout << "Test array: \n";
|
||||
vtkm::cont::printSummary_ArrayHandle(array, std::cout, true);
|
||||
std::cout << "Mask array: \n";
|
||||
vtkm::cont::printSummary_ArrayHandle(maskArray, std::cout, true);
|
||||
std::cout << "Range type: " << (finitesOnly ? "Vector, Finite" : "Vector, NonFinite") << "\n";
|
||||
std::cout << "Computed range: " << computedRange << "\n";
|
||||
std::cout << "Expected range: " << expectedRange << "\n";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
auto FillMaskArray(vtkm::Id length)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> maskArray;
|
||||
maskArray.Allocate(length);
|
||||
|
||||
vtkm::cont::ArrayHandleRandomUniformBits randomBits(length + 1);
|
||||
auto randomPortal = randomBits.ReadPortal();
|
||||
switch (randomPortal.Get(length) % 3)
|
||||
{
|
||||
case 0: // all masked
|
||||
maskArray.Fill(0);
|
||||
break;
|
||||
case 1: // none masked
|
||||
maskArray.Fill(1);
|
||||
break;
|
||||
case 2: // random masked
|
||||
default:
|
||||
{
|
||||
auto maskPortal = maskArray.WritePortal();
|
||||
for (vtkm::Id i = 0; i < length; ++i)
|
||||
{
|
||||
vtkm::UInt8 maskVal = ((randomPortal.Get(i) % 8) == 0) ? 0 : 1;
|
||||
maskPortal.Set(i, maskVal);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return maskArray;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||
{
|
||||
VerifyRange(array, vtkm::cont::ArrayRangeCompute(array));
|
||||
auto length = array.GetNumberOfValues();
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> emptyMaskArray;
|
||||
|
||||
auto maskArray = FillMaskArray(length);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> scalarRange;
|
||||
std::cout << "\tchecking scalar range without mask\n";
|
||||
scalarRange = vtkm::cont::ArrayRangeCompute(array);
|
||||
VerifyRangeScalar(array, scalarRange, emptyMaskArray, false);
|
||||
std::cout << "\tchecking scalar range with mask\n";
|
||||
scalarRange = vtkm::cont::ArrayRangeCompute(array, maskArray);
|
||||
VerifyRangeScalar(array, scalarRange, maskArray, false);
|
||||
|
||||
vtkm::Range vectorRange;
|
||||
std::cout << "\tchecking vector range without mask\n";
|
||||
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array);
|
||||
VerifyRangeVector(array, vectorRange, emptyMaskArray, false);
|
||||
std::cout << "\tchecking vector range with mask\n";
|
||||
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array, maskArray);
|
||||
VerifyRangeVector(array, vectorRange, maskArray, false);
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
void CheckRangeFiniteImpl(const ArrayHandleType& array, std::true_type)
|
||||
{
|
||||
auto length = array.GetNumberOfValues();
|
||||
vtkm::cont::ArrayHandle<vtkm::UInt8> emptyMaskArray;
|
||||
|
||||
auto maskArray = FillMaskArray(length);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> scalarRange;
|
||||
std::cout << "\tchecking finite scalar range without mask\n";
|
||||
scalarRange = vtkm::cont::ArrayRangeCompute(array, true);
|
||||
VerifyRangeScalar(array, scalarRange, emptyMaskArray, true);
|
||||
std::cout << "\tchecking finite scalar range with mask\n";
|
||||
scalarRange = vtkm::cont::ArrayRangeCompute(array, maskArray, true);
|
||||
VerifyRangeScalar(array, scalarRange, maskArray, true);
|
||||
|
||||
vtkm::Range vectorRange;
|
||||
std::cout << "\tchecking finite vector range without mask\n";
|
||||
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array, true);
|
||||
VerifyRangeVector(array, vectorRange, emptyMaskArray, true);
|
||||
std::cout << "\tchecking finite vector range with mask\n";
|
||||
vectorRange = vtkm::cont::ArrayRangeComputeMagnitude(array, maskArray, true);
|
||||
VerifyRangeVector(array, vectorRange, maskArray, true);
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
void CheckRangeFiniteImpl(const ArrayHandleType&, std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
void FillArray(vtkm::cont::ArrayHandle<T, S>& array)
|
||||
void CheckRangeFinite(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||
{
|
||||
using ComponentType = typename vtkm::VecTraits<T>::ComponentType;
|
||||
auto tag = std::integral_constant < bool,
|
||||
std::is_same<ComponentType, vtkm::Float32>::value ||
|
||||
std::is_same<ComponentType, vtkm::Float64>::value > {};
|
||||
CheckRangeFiniteImpl(array, tag);
|
||||
}
|
||||
|
||||
// Transform random values in range [0, 1) to the range [From, To).
|
||||
// If the `AddNonFinites` flag is set, some values are transformed to non-finite values.
|
||||
struct TransformRange
|
||||
{
|
||||
vtkm::Float64 From, To;
|
||||
bool AddNonFinites = false;
|
||||
|
||||
VTKM_EXEC vtkm::Float64 operator()(vtkm::Float64 in) const
|
||||
{
|
||||
if (AddNonFinites)
|
||||
{
|
||||
if (in >= 0.3 && in <= 0.33)
|
||||
{
|
||||
return vtkm::NegativeInfinity64();
|
||||
}
|
||||
if (in >= 0.9 && in <= 0.93)
|
||||
{
|
||||
return vtkm::Infinity64();
|
||||
}
|
||||
}
|
||||
return (in * (this->To - this->From)) + this->From;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename S>
|
||||
void FillArray(vtkm::cont::ArrayHandle<T, S>& array, bool addNonFinites)
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
|
||||
|
||||
// non-finites only applies to floating point types
|
||||
addNonFinites = addNonFinites &&
|
||||
(std::is_same<typename Traits::ComponentType, vtkm::Float32>::value ||
|
||||
std::is_same<typename Traits::ComponentType, vtkm::Float64>::value);
|
||||
|
||||
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::ArrayCopyDevice(randomArray, dest);
|
||||
auto transformFunctor = std::numeric_limits<typename Traits::BaseComponentType>::is_signed
|
||||
? TransformRange{ -100.0, 100.0, addNonFinites }
|
||||
: TransformRange{ 0.0, 200.0, addNonFinites };
|
||||
vtkm::cont::ArrayCopyDevice(
|
||||
vtkm::cont::make_ArrayHandleTransform(randomArray, transformFunctor), dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,8 +287,10 @@ void TestBasicArray()
|
||||
{
|
||||
std::cout << "Checking basic array" << std::endl;
|
||||
vtkm::cont::ArrayHandleBasic<T> array;
|
||||
FillArray(array);
|
||||
FillArray(array, false);
|
||||
CheckRange(array);
|
||||
FillArray(array, true);
|
||||
CheckRangeFinite(array);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -97,8 +298,10 @@ void TestSOAArray(vtkm::TypeTraitsVectorTag)
|
||||
{
|
||||
std::cout << "Checking SOA array" << std::endl;
|
||||
vtkm::cont::ArrayHandleSOA<T> array;
|
||||
FillArray(array);
|
||||
FillArray(array, false);
|
||||
CheckRange(array);
|
||||
FillArray(array, true);
|
||||
CheckRangeFinite(array);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -112,8 +315,10 @@ void TestStrideArray()
|
||||
{
|
||||
std::cout << "Checking stride array" << std::endl;
|
||||
vtkm::cont::ArrayHandleBasic<T> array;
|
||||
FillArray(array);
|
||||
FillArray(array, false);
|
||||
CheckRange(vtkm::cont::ArrayHandleStride<T>(array, ARRAY_SIZE / 2, 2, 1));
|
||||
FillArray(array, true);
|
||||
CheckRangeFinite(vtkm::cont::ArrayHandleStride<T>(array, ARRAY_SIZE / 2, 2, 1));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -122,23 +327,30 @@ void TestCastArray()
|
||||
std::cout << "Checking cast array" << std::endl;
|
||||
using CastType = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::Float64>;
|
||||
vtkm::cont::ArrayHandle<T> array;
|
||||
FillArray(array);
|
||||
FillArray(array, false);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleCast<CastType>(array));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto FillCartesianProductArray(bool addNonFinites)
|
||||
{
|
||||
vtkm::cont::ArrayHandleBasic<T> array0;
|
||||
FillArray(array0, addNonFinites);
|
||||
vtkm::cont::ArrayHandleBasic<T> array1;
|
||||
FillArray(array1, addNonFinites);
|
||||
vtkm::cont::ArrayHandleBasic<T> array2;
|
||||
FillArray(array2, addNonFinites);
|
||||
return vtkm::cont::make_ArrayHandleCartesianProduct(array0, array1, array2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestCartesianProduct(vtkm::TypeTraitsScalarTag)
|
||||
{
|
||||
std::cout << "Checking Cartesian product" << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandleBasic<T> array0;
|
||||
FillArray(array0);
|
||||
vtkm::cont::ArrayHandleBasic<T> array1;
|
||||
FillArray(array1);
|
||||
vtkm::cont::ArrayHandleBasic<T> array2;
|
||||
FillArray(array2);
|
||||
|
||||
CheckRange(vtkm::cont::make_ArrayHandleCartesianProduct(array0, array1, array2));
|
||||
auto array = FillCartesianProductArray<T>(false);
|
||||
CheckRange(array);
|
||||
array = FillCartesianProductArray<T>(true);
|
||||
CheckRangeFinite(array);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -147,19 +359,27 @@ void TestCartesianProduct(vtkm::TypeTraitsVectorTag)
|
||||
// Skip test.
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto FillCompositeVectorArray(bool addNonFinites)
|
||||
{
|
||||
vtkm::cont::ArrayHandleBasic<T> array0;
|
||||
FillArray(array0, addNonFinites);
|
||||
vtkm::cont::ArrayHandleBasic<T> array1;
|
||||
FillArray(array1, addNonFinites);
|
||||
vtkm::cont::ArrayHandleBasic<T> array2;
|
||||
FillArray(array2, addNonFinites);
|
||||
return vtkm::cont::make_ArrayHandleCompositeVector(array0, array1, array2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestComposite(vtkm::TypeTraitsScalarTag)
|
||||
{
|
||||
std::cout << "Checking composite vector array" << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandleBasic<T> array0;
|
||||
FillArray(array0);
|
||||
vtkm::cont::ArrayHandleBasic<T> array1;
|
||||
FillArray(array1);
|
||||
vtkm::cont::ArrayHandleBasic<T> array2;
|
||||
FillArray(array2);
|
||||
|
||||
CheckRange(vtkm::cont::make_ArrayHandleCompositeVector(array0, array1, array2));
|
||||
auto array = FillCompositeVectorArray<T>(false);
|
||||
CheckRange(array);
|
||||
array = FillCompositeVectorArray<T>(true);
|
||||
CheckRangeFinite(array);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -174,8 +394,10 @@ void TestGroup(vtkm::TypeTraitsScalarTag)
|
||||
std::cout << "Checking group vec array" << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandleBasic<T> array;
|
||||
FillArray(array);
|
||||
FillArray(array, false);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleGroupVec<2>(array));
|
||||
FillArray(array, true);
|
||||
CheckRangeFinite(vtkm::cont::make_ArrayHandleGroupVec<2>(array));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -190,8 +412,10 @@ void TestView()
|
||||
std::cout << "Checking view array" << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandleBasic<T> array;
|
||||
FillArray(array);
|
||||
FillArray(array, false);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleView(array, 2, ARRAY_SIZE - 5));
|
||||
FillArray(array, true);
|
||||
CheckRangeFinite(vtkm::cont::make_ArrayHandleView(array, 2, ARRAY_SIZE - 5));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -234,8 +458,10 @@ void TestXGCCoordinates()
|
||||
{
|
||||
std::cout << "Checking XGC coordinates array" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array;
|
||||
FillArray(array);
|
||||
FillArray(array, false);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleXGCCoordinates(array, 4, true));
|
||||
FillArray(array, true);
|
||||
CheckRangeFinite(vtkm::cont::make_ArrayHandleXGCCoordinates(array, 4, true));
|
||||
}
|
||||
|
||||
struct DoTestFunctor
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||
#include <vtkm/cont/CellSetSingleType.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DataSetBuilderExplicit.h>
|
||||
|
@ -73,8 +73,6 @@
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||
#include <vtkm/cont/ArrayPortalToIterators.h>
|
||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||
#include <vtkm/cont/ConvertNumComponentsToOffsets.h>
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
@ -576,9 +574,7 @@ template <typename FieldType>
|
||||
inline void ContourTreeMesh<FieldType>::ComputeMaxNeighbors()
|
||||
{
|
||||
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray =
|
||||
vtkm::cont::ArrayRangeComputeTemplate(neighborCounts);
|
||||
this->MaxNeighbors = static_cast<vtkm::Id>(rangeArray.ReadPortal().Get(0).Max);
|
||||
this->MaxNeighbors = vtkm::cont::Algorithm::Reduce(neighborCounts, 0, vtkm::Maximum{});
|
||||
}
|
||||
|
||||
// Define the behavior for the execution object generate by the PrepareForExecution function
|
||||
|
Loading…
Reference in New Issue
Block a user