mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge topic 'array-range-fast-paths'
58fc99c2f Fix fast paths for ArrayRangeCompute 4b19139f3 Add tests to UnitTestArrayRangeCompute Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3008
This commit is contained in:
commit
6d99c77052
18
docs/changelog/array-range-fast-paths.md
Normal file
18
docs/changelog/array-range-fast-paths.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Fast paths for `ArrayRangeCompute` fixed
|
||||
|
||||
The precompiled `ArrayRangeCompute` function was not following proper fast
|
||||
paths for special arrays. For example, when computing the range of an
|
||||
`ArrayHandleUniformPointCoordinates`, the ranges should be taken from the
|
||||
origin and spacing of the special array. However, the precompiled version
|
||||
was calling the generic range computation, which was doing an unnecessary
|
||||
reduction over the entire array. These fast paths have been fixed.
|
||||
|
||||
These mistakes in the code were caused by quirks in how templated method
|
||||
overloading works. To prevent this mistake from happening again in the
|
||||
precompiled `ArrayRangeCompute` function and elsewhere, all templated forms
|
||||
of `ArrayRangeCompute` have been deprecated. Most will call
|
||||
`ArrayRangeCompute` with no issues. For those that need the templated
|
||||
version, `ArrayRangeComputeTemplate` replaces the old templated
|
||||
`ArrayRangeCompute`. There is exactly one templated declaration of
|
||||
`ArrayRangeComputeTemplate` that uses a class, `ArrayRangeComputeImpl`,
|
||||
with partial specialization to ensure the correct form is used.
|
@ -11,6 +11,8 @@
|
||||
#define vtk_m_cont_ArrayHandleCartesianProduct_h
|
||||
|
||||
#include <vtkm/Assert.h>
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/ArrayExtractComponent.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
@ -486,6 +488,77 @@ struct ArrayExtractComponentImpl<vtkm::cont::StorageTagCartesianProduct<STs...>>
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl;
|
||||
|
||||
template <typename ST1, typename ST2, typename ST3>
|
||||
struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>
|
||||
{
|
||||
template <typename T>
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>,
|
||||
vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>& input_,
|
||||
vtkm::cont::DeviceAdapterId device) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(3);
|
||||
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)
|
||||
{
|
||||
result.Allocate(result.GetNumberOfValues() + numSubComponents - 1, vtkm::CopyFlag::On);
|
||||
resultPortal = result.WritePortal();
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
|
@ -12,6 +12,9 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/VecFlat.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
@ -90,6 +93,36 @@ vtkm::cont::ArrayHandleConstant<T> make_ArrayHandleConstant(T value, vtkm::Id nu
|
||||
{
|
||||
return vtkm::cont::ArrayHandleConstant<T>(value, numberOfValues);
|
||||
}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl;
|
||||
|
||||
template <>
|
||||
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
|
||||
{
|
||||
auto value = vtkm::make_VecFlat(input.ReadPortal().Get(0));
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(value.GetNumberOfComponents());
|
||||
auto resultPortal = result.WritePortal();
|
||||
for (vtkm::IdComponent index = 0; index < value.GetNumberOfComponents(); ++index)
|
||||
{
|
||||
resultPortal.Set(index, vtkm::Range{ value[index], value[index] });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
} // vtkm::cont
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/TypeTraits.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
@ -152,6 +153,52 @@ make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::
|
||||
{
|
||||
return vtkm::cont::ArrayHandleCounting<CountingValueType>(start, step, length);
|
||||
}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl;
|
||||
|
||||
template <>
|
||||
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
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(Traits::NUM_COMPONENTS);
|
||||
auto portal = result.WritePortal();
|
||||
if (portal.GetNumberOfValues() > 0)
|
||||
{
|
||||
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{});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef vtk_m_cont_ArrayHandleIndex_h
|
||||
#define vtk_m_cont_ArrayHandleIndex_h
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
|
||||
namespace vtkm
|
||||
@ -71,6 +72,29 @@ VTKM_CONT inline vtkm::cont::ArrayHandleIndex make_ArrayHandleIndex(vtkm::Id len
|
||||
{
|
||||
return vtkm::cont::ArrayHandleIndex(length);
|
||||
}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl;
|
||||
|
||||
template <>
|
||||
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
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(1);
|
||||
result.WritePortal().Set(0, vtkm::Range(0, input.GetNumberOfValues() - 1));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
|
@ -86,6 +86,28 @@ 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
|
||||
{
|
||||
vtkm::internal::ArrayPortalUniformPointCoordinates portal = input.ReadPortal();
|
||||
|
||||
// In this portal we know that the min value is the first entry and the
|
||||
// max value is the last entry.
|
||||
vtkm::Vec3f minimum = portal.Get(0);
|
||||
vtkm::Vec3f maximum = portal.Get(portal.GetNumberOfValues() - 1);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray;
|
||||
rangeArray.Allocate(3);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range>::WritePortalType outPortal = rangeArray.WritePortal();
|
||||
outPortal.Set(0, vtkm::Range(minimum[0], maximum[0]));
|
||||
outPortal.Set(1, vtkm::Range(minimum[1], maximum[1]));
|
||||
outPortal.Set(2, vtkm::Range(minimum[2], maximum[2]));
|
||||
|
||||
return rangeArray;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef vtk_m_cont_ArrayHandleUniformPointCoordinates_h
|
||||
#define vtk_m_cont_ArrayHandleUniformPointCoordinates_h
|
||||
|
||||
#include <vtkm/Range.h>
|
||||
#include <vtkm/cont/ArrayExtractComponent.h>
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
#include <vtkm/internal/ArrayPortalUniformPointCoordinates.h>
|
||||
@ -83,6 +84,17 @@ struct VTKM_CONT_EXPORT ArrayExtractComponentImpl<vtkm::cont::StorageTagUniformP
|
||||
vtkm::CopyFlag allowCopy) const;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct ArrayRangeComputeImpl;
|
||||
|
||||
template <>
|
||||
struct VTKM_CONT_EXPORT ArrayRangeComputeImpl<vtkm::cont::StorageTagUniformPoints>
|
||||
{
|
||||
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> operator()(
|
||||
const vtkm::cont::ArrayHandleUniformPointCoordinates& input,
|
||||
vtkm::cont::DeviceAdapterId device) const;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
}
|
||||
|
@ -12,118 +12,16 @@
|
||||
|
||||
#include <vtkm/TypeList.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
void ThrowArrayRangeComputeFailed()
|
||||
{
|
||||
throw vtkm::cont::ErrorExecution("Failed to run ArrayRangeComputation on any device.");
|
||||
}
|
||||
|
||||
#define VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(T, Storage) \
|
||||
VTKM_CONT \
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute( \
|
||||
const vtkm::cont::ArrayHandle<T, Storage>& input, vtkm::cont::DeviceAdapterId device) \
|
||||
{ \
|
||||
return detail::ArrayRangeComputeImpl(input, device); \
|
||||
} \
|
||||
struct SwallowSemicolon
|
||||
#define VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(T, N, Storage) \
|
||||
VTKM_CONT \
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, Storage>& input, \
|
||||
vtkm::cont::DeviceAdapterId device) \
|
||||
{ \
|
||||
return detail::ArrayRangeComputeImpl(input, device); \
|
||||
} \
|
||||
struct SwallowSemicolon
|
||||
|
||||
#define VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_SCALAR_T(Storage) \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::Int8, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::UInt8, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::Int16, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::UInt16, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::Int32, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::UInt32, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::Int64, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::UInt64, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::Float32, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(vtkm::Float64, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(char, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(signed VTKM_UNUSED_INT_TYPE, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_T(unsigned VTKM_UNUSED_INT_TYPE, Storage)
|
||||
|
||||
#define VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC(N, Storage) \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Int8, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::UInt8, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Int16, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::UInt16, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Int32, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::UInt32, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Int64, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::UInt64, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float32, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float64, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(char, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(signed VTKM_UNUSED_INT_TYPE, N, Storage); \
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(unsigned VTKM_UNUSED_INT_TYPE, N, Storage)
|
||||
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_SCALAR_T(vtkm::cont::StorageTagBasic);
|
||||
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC(2, vtkm::cont::StorageTagBasic);
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC(3, vtkm::cont::StorageTagBasic);
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC(4, vtkm::cont::StorageTagBasic);
|
||||
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC(2, vtkm::cont::StorageTagSOA);
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC(3, vtkm::cont::StorageTagSOA);
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC(4, vtkm::cont::StorageTagSOA);
|
||||
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_SCALAR_T(vtkm::cont::StorageTagStride);
|
||||
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float32, 3, vtkm::cont::StorageTagXGCCoordinates);
|
||||
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float64, 3, vtkm::cont::StorageTagXGCCoordinates);
|
||||
|
||||
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_T
|
||||
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC
|
||||
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_SCALAR_T
|
||||
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_ALL_VEC
|
||||
|
||||
// Special implementation for regular point coordinates, which are easy
|
||||
// to determine.
|
||||
VTKM_CONT
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec3f,
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag>& array,
|
||||
vtkm::cont::DeviceAdapterId)
|
||||
{
|
||||
vtkm::internal::ArrayPortalUniformPointCoordinates portal = array.ReadPortal();
|
||||
|
||||
// In this portal we know that the min value is the first entry and the
|
||||
// max value is the last entry.
|
||||
vtkm::Vec3f minimum = portal.Get(0);
|
||||
vtkm::Vec3f maximum = portal.Get(portal.GetNumberOfValues() - 1);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray;
|
||||
rangeArray.Allocate(3);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range>::WritePortalType outPortal = rangeArray.WritePortal();
|
||||
outPortal.Set(0, vtkm::Range(minimum[0], maximum[0]));
|
||||
outPortal.Set(1, vtkm::Range(minimum[1], maximum[1]));
|
||||
outPortal.Set(2, vtkm::Range(minimum[2], maximum[2]));
|
||||
|
||||
return rangeArray;
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||
vtkm::cont::DeviceAdapterId)
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(1);
|
||||
result.WritePortal().Set(0, vtkm::Range(0, input.GetNumberOfValues() - 1));
|
||||
return result;
|
||||
}
|
||||
#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>
|
||||
#include <vtkm/cont/ArrayHandleSOA.h>
|
||||
#include <vtkm/cont/ArrayHandleStride.h>
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -152,7 +50,7 @@ struct ComputeRangeFunctor
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::ArrayHandle<vtkm::Range>& ranges) const
|
||||
{
|
||||
ranges = vtkm::cont::ArrayRangeCompute(array, device);
|
||||
ranges = vtkm::cont::ArrayRangeComputeTemplate(array, device);
|
||||
}
|
||||
|
||||
// Used with vtkm::ListForEach to get components
|
||||
@ -172,7 +70,7 @@ struct ComputeRangeFunctor
|
||||
{
|
||||
vtkm::cont::ArrayHandleStride<T> componentArray = array.ExtractComponent<T>(componentI);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> componentRange =
|
||||
vtkm::cont::ArrayRangeCompute(componentArray, device);
|
||||
vtkm::cont::ArrayRangeComputeTemplate(componentArray, device);
|
||||
rangePortal.Set(componentI, componentRange.ReadPortal().Get(0));
|
||||
}
|
||||
success = true;
|
||||
@ -191,6 +89,21 @@ vtkm::cont::ArrayHandle<vtkm::Range> ComputeForStorage(const vtkm::cont::Unknown
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
void ThrowArrayRangeComputeFailed()
|
||||
{
|
||||
throw vtkm::cont::ErrorExecution("Failed to run ArrayRangeComputation on any device.");
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::UnknownArrayHandle& array,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
@ -214,7 +127,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::Unknown
|
||||
{
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates uniformPoints;
|
||||
array.AsArrayHandle(uniformPoints);
|
||||
return vtkm::cont::ArrayRangeCompute(uniformPoints, device);
|
||||
return vtkm::cont::ArrayRangeComputeTemplate(uniformPoints, device);
|
||||
}
|
||||
using CartesianProductStorage =
|
||||
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
||||
@ -234,7 +147,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::Unknown
|
||||
}
|
||||
if (array.IsStorageType<vtkm::cont::StorageTagIndex>())
|
||||
{
|
||||
return ArrayRangeCompute(array.AsArrayHandle<vtkm::cont::ArrayHandleIndex>(), device);
|
||||
return ArrayRangeComputeTemplate(array.AsArrayHandle<vtkm::cont::ArrayHandleIndex>(), device);
|
||||
}
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadType&)
|
||||
|
@ -31,7 +31,6 @@ 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
|
||||
@ -48,179 +47,27 @@ namespace cont
|
||||
/// 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 include
|
||||
/// ArrayRangeComputeTemplate.h. This contains a templated version of ArrayRangeCompute
|
||||
/// that will compile for any `ArrayHandle` type not already handled.
|
||||
/// 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.
|
||||
///
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::UnknownArrayHandle& array,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(T, Storage) \
|
||||
VTKM_CONT_EXPORT \
|
||||
VTKM_CONT \
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute( \
|
||||
const vtkm::cont::ArrayHandle<T, Storage>& input, \
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny())
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(T, N, Storage) \
|
||||
VTKM_CONT_EXPORT \
|
||||
VTKM_CONT \
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute( \
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, Storage>& input, \
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny())
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_SCALAR_T(Storage) \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int8, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt8, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int16, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt16, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int32, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt32, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Int64, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::UInt64, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Float32, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(vtkm::Float64, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(char, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(signed VTKM_UNUSED_INT_TYPE, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(unsigned VTKM_UNUSED_INT_TYPE, Storage)
|
||||
|
||||
#define VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC(N, Storage) \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int8, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::UInt8, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int16, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::UInt16, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int32, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::UInt32, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Int64, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::UInt64, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float32, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(char, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(signed VTKM_UNUSED_INT_TYPE, N, Storage); \
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(unsigned VTKM_UNUSED_INT_TYPE, N, Storage)
|
||||
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_SCALAR_T(vtkm::cont::StorageTagBasic);
|
||||
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC(2, vtkm::cont::StorageTagBasic);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC(3, vtkm::cont::StorageTagBasic);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC(4, vtkm::cont::StorageTagBasic);
|
||||
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC(2, vtkm::cont::StorageTagSOA);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC(3, vtkm::cont::StorageTagSOA);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC(4, vtkm::cont::StorageTagSOA);
|
||||
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_SCALAR_T(vtkm::cont::StorageTagStride);
|
||||
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float32, 3, vtkm::cont::StorageTagXGCCoordinates);
|
||||
VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 3, vtkm::cont::StorageTagXGCCoordinates);
|
||||
|
||||
#undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T
|
||||
#undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC
|
||||
#undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_SCALAR_T
|
||||
#undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_ALL_VEC
|
||||
|
||||
VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec3f,
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag>& array,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
|
||||
|
||||
// Implementation of cartesian products
|
||||
template <typename T, typename ST1, typename ST2, typename ST3>
|
||||
VTKM_CONT inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>,
|
||||
vtkm::cont::StorageTagCartesianProduct<ST1, ST2, ST3>>& input_,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny())
|
||||
namespace internal
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(3);
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> componentRangeArray;
|
||||
vtkm::Range componentRange;
|
||||
|
||||
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T, ST1>,
|
||||
vtkm::cont::ArrayHandle<T, ST2>,
|
||||
vtkm::cont::ArrayHandle<T, ST3>>
|
||||
input = input_;
|
||||
vtkm::cont::ArrayHandle<T, ST1> firstArray = input.GetFirstArray();
|
||||
componentRangeArray = vtkm::cont::ArrayRangeCompute(firstArray, device);
|
||||
componentRange = componentRangeArray.ReadPortal().Get(0);
|
||||
result.WritePortal().Set(0, componentRange);
|
||||
|
||||
vtkm::cont::ArrayHandle<T, ST2> secondArray = input.GetSecondArray();
|
||||
componentRangeArray = vtkm::cont::ArrayRangeCompute(secondArray, device);
|
||||
componentRange = componentRangeArray.ReadPortal().Get(0);
|
||||
result.WritePortal().Set(1, componentRange);
|
||||
|
||||
vtkm::cont::ArrayHandle<T, ST3> thirdArray = input.GetThirdArray();
|
||||
componentRangeArray = vtkm::cont::ArrayRangeCompute(thirdArray, device);
|
||||
componentRange = componentRangeArray.ReadPortal().Get(0);
|
||||
result.WritePortal().Set(2, componentRange);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implementation of constant arrays
|
||||
template <typename T>
|
||||
VTKM_CONT inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagConstant>& input,
|
||||
vtkm::cont::DeviceAdapterId vtkmNotUsed(device) = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
const T value = vtkm::cont::ArrayHandleConstant<T>(input).GetValue();
|
||||
vtkm::IdComponent numComponents = Traits::GetNumberOfComponents(value);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(numComponents);
|
||||
auto portal = result.WritePortal();
|
||||
for (vtkm::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
|
||||
{
|
||||
auto component = Traits::GetComponent(value, cIndex);
|
||||
portal.Set(cIndex, vtkm::Range(component, component));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implementation of counting arrays
|
||||
template <typename T>
|
||||
VTKM_CONT inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagCounting>& input,
|
||||
vtkm::cont::DeviceAdapterId vtkmNotUsed(device) = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> result;
|
||||
result.Allocate(Traits::NUM_COMPONENTS);
|
||||
auto portal = result.WritePortal();
|
||||
if (portal.GetNumberOfValues() > 0)
|
||||
{
|
||||
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{});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implementation of index arrays
|
||||
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||
///@}
|
||||
|
||||
VTKM_CONT_EXPORT void ThrowArrayRangeComputeFailed();
|
||||
|
||||
} // namespace internal
|
||||
|
||||
VTKM_DEPRECATED(2.1, "Moved to vtkm::cont::internal.")
|
||||
inline void ThrowArrayRangeComputeFailed()
|
||||
{
|
||||
internal::ThrowArrayRangeComputeFailed();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||
|
||||
#include <vtkm/BinaryOperators.h>
|
||||
#include <vtkm/Deprecated.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/Algorithm.h>
|
||||
@ -42,8 +43,13 @@ struct ArrayRangeComputeFunctor
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
template <typename T, typename S>
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImpl(
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeGeneric(
|
||||
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||
vtkm::cont::DeviceAdapterId device)
|
||||
{
|
||||
@ -74,7 +80,7 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImpl(
|
||||
initial[1] = T(std::numeric_limits<CT>::lowest());
|
||||
|
||||
const bool rangeComputed = vtkm::cont::TryExecuteOnDevice(
|
||||
device, detail::ArrayRangeComputeFunctor{}, input, initial, result);
|
||||
device, vtkm::cont::detail::ArrayRangeComputeFunctor{}, input, initial, result);
|
||||
if (!rangeComputed)
|
||||
{
|
||||
ThrowArrayRangeComputeFailed();
|
||||
@ -93,17 +99,38 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImpl(
|
||||
return range;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
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
|
||||
{
|
||||
return vtkm::cont::internal::ArrayRangeComputeGeneric(input, device);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||
const ArrayHandleType& input,
|
||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
return detail::ArrayRangeComputeImpl(input, device);
|
||||
return internal::ArrayRangeComputeImpl<typename ArrayHandleType::StorageTag>{}(input, 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);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
||||
|
@ -11,17 +11,22 @@
|
||||
#include <vtkm/cont/ArrayCopyDevice.h>
|
||||
#include <vtkm/cont/ArrayHandleBasic.h>
|
||||
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleExtractComponent.h>
|
||||
#include <vtkm/cont/ArrayHandleGroupVec.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/ArrayHandleRandomUniformReal.h>
|
||||
#include <vtkm/cont/ArrayHandleSOA.h>
|
||||
#include <vtkm/cont/ArrayHandleStride.h>
|
||||
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||
#include <vtkm/cont/ArrayHandleView.h>
|
||||
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
|
||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||
|
||||
#include <vtkm/Math.h>
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
@ -31,12 +36,12 @@ namespace
|
||||
constexpr vtkm::Id ARRAY_SIZE = 20;
|
||||
|
||||
template <typename T, typename S>
|
||||
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array, bool checkUnknown = true)
|
||||
void VerifyRange(const vtkm::cont::ArrayHandle<T, S>& array,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Range>& computedRangeArray)
|
||||
{
|
||||
using Traits = vtkm::VecTraits<T>;
|
||||
vtkm::IdComponent numComponents = Traits::NUM_COMPONENTS;
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> computedRangeArray = vtkm::cont::ArrayRangeCompute(array);
|
||||
VTKM_TEST_ASSERT(computedRangeArray.GetNumberOfValues() == numComponents);
|
||||
auto computedRangePortal = computedRangeArray.ReadPortal();
|
||||
|
||||
@ -54,28 +59,12 @@ void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array, bool checkUnknown =
|
||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Max));
|
||||
VTKM_TEST_ASSERT(test_equal(expectedRange, computedRange));
|
||||
}
|
||||
}
|
||||
|
||||
if (checkUnknown)
|
||||
{
|
||||
computedRangeArray = vtkm::cont::ArrayRangeCompute(vtkm::cont::UnknownArrayHandle{ array });
|
||||
VTKM_TEST_ASSERT(computedRangeArray.GetNumberOfValues() == numComponents);
|
||||
computedRangePortal = computedRangeArray.ReadPortal();
|
||||
|
||||
portal = array.ReadPortal();
|
||||
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
|
||||
{
|
||||
vtkm::Range computedRange = computedRangePortal.Get(component);
|
||||
vtkm::Range expectedRange;
|
||||
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); ++index)
|
||||
{
|
||||
T value = portal.Get(index);
|
||||
expectedRange.Include(Traits::GetComponent(value, component));
|
||||
}
|
||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Min));
|
||||
VTKM_TEST_ASSERT(!vtkm::IsNan(computedRange.Max));
|
||||
VTKM_TEST_ASSERT(test_equal(expectedRange, computedRange));
|
||||
}
|
||||
}
|
||||
template <typename T, typename S>
|
||||
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||
{
|
||||
VerifyRange(array, vtkm::cont::ArrayRangeCompute(array));
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
@ -119,7 +108,7 @@ void TestSOAArray(vtkm::TypeTraitsScalarTag)
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestStrideArray(vtkm::TypeTraitsScalarTag)
|
||||
void TestStrideArray()
|
||||
{
|
||||
std::cout << "Checking stride array" << std::endl;
|
||||
vtkm::cont::ArrayHandleBasic<T> array;
|
||||
@ -127,6 +116,16 @@ void TestStrideArray(vtkm::TypeTraitsScalarTag)
|
||||
CheckRange(vtkm::cont::ArrayHandleStride<T>(array, ARRAY_SIZE / 2, 2, 1));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleCast<CastType>(array));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestCartesianProduct(vtkm::TypeTraitsScalarTag)
|
||||
{
|
||||
@ -151,7 +150,7 @@ void TestCartesianProduct(vtkm::TypeTraitsVectorTag)
|
||||
template <typename T>
|
||||
void TestComposite(vtkm::TypeTraitsScalarTag)
|
||||
{
|
||||
std::cout << "Checking composite vector" << std::endl;
|
||||
std::cout << "Checking composite vector array" << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandleBasic<T> array0;
|
||||
FillArray(array0);
|
||||
@ -169,6 +168,32 @@ void TestComposite(vtkm::TypeTraitsVectorTag)
|
||||
// Skip test.
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestGroup(vtkm::TypeTraitsScalarTag)
|
||||
{
|
||||
std::cout << "Checking group vec array" << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandleBasic<T> array;
|
||||
FillArray(array);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleGroupVec<2>(array));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestGroup(vtkm::TypeTraitsVectorTag)
|
||||
{
|
||||
// Skip test.
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestView()
|
||||
{
|
||||
std::cout << "Checking view array" << std::endl;
|
||||
|
||||
vtkm::cont::ArrayHandleBasic<T> array;
|
||||
FillArray(array);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleView(array, 2, ARRAY_SIZE - 5));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestConstant()
|
||||
{
|
||||
@ -205,15 +230,29 @@ void TestUniformPointCoords()
|
||||
vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(ARRAY_SIZE, ARRAY_SIZE, ARRAY_SIZE)));
|
||||
}
|
||||
|
||||
void TestXGCCoordinates()
|
||||
{
|
||||
std::cout << "Checking XGC coordinates array" << std::endl;
|
||||
vtkm::cont::ArrayHandle<vtkm::FloatDefault> array;
|
||||
FillArray(array);
|
||||
CheckRange(vtkm::cont::make_ArrayHandleXGCCoordinates(array, 4, true));
|
||||
}
|
||||
|
||||
struct DoTestFunctor
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(T) const
|
||||
{
|
||||
typename vtkm::TypeTraits<T>::DimensionalityTag dimensionality{};
|
||||
|
||||
TestBasicArray<T>();
|
||||
TestSOAArray<T>(typename vtkm::TypeTraits<T>::DimensionalityTag{});
|
||||
TestCartesianProduct<T>(typename vtkm::TypeTraits<T>::DimensionalityTag{});
|
||||
TestComposite<T>(typename vtkm::TypeTraits<T>::DimensionalityTag{});
|
||||
TestSOAArray<T>(dimensionality);
|
||||
TestStrideArray<T>();
|
||||
TestCastArray<T>();
|
||||
TestCartesianProduct<T>(dimensionality);
|
||||
TestComposite<T>(dimensionality);
|
||||
TestGroup<T>(dimensionality);
|
||||
TestView<T>();
|
||||
TestConstant<T>();
|
||||
TestCounting<T>(typename std::is_signed<typename vtkm::VecTraits<T>::ComponentType>::type{});
|
||||
}
|
||||
@ -226,6 +265,7 @@ void DoTest()
|
||||
std::cout << "*** Specific arrays *****************" << std::endl;
|
||||
TestIndex();
|
||||
TestUniformPointCoords();
|
||||
TestXGCCoordinates();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -576,7 +576,8 @@ template <typename FieldType>
|
||||
inline void ContourTreeMesh<FieldType>::ComputeMaxNeighbors()
|
||||
{
|
||||
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray = vtkm::cont::ArrayRangeCompute(neighborCounts);
|
||||
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray =
|
||||
vtkm::cont::ArrayRangeComputeTemplate(neighborCounts);
|
||||
this->MaxNeighbors = static_cast<vtkm::Id>(rangeArray.ReadPortal().Get(0).Max);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
||||
#include <vtkm/cont/BitField.h>
|
||||
#include <vtkm/cont/Invoker.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
|
Loading…
Reference in New Issue
Block a user