mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Fix fast paths for ArrayRangeCompute
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.
This commit is contained in:
parent
4b19139f3d
commit
58fc99c2f8
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
|
#define vtk_m_cont_ArrayHandleCartesianProduct_h
|
||||||
|
|
||||||
#include <vtkm/Assert.h>
|
#include <vtkm/Assert.h>
|
||||||
|
#include <vtkm/Range.h>
|
||||||
|
#include <vtkm/VecTraits.h>
|
||||||
|
|
||||||
#include <vtkm/cont/ArrayExtractComponent.h>
|
#include <vtkm/cont/ArrayExtractComponent.h>
|
||||||
#include <vtkm/cont/ArrayHandle.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
|
} // namespace internal
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||||
|
|
||||||
|
#include <vtkm/Range.h>
|
||||||
|
#include <vtkm/VecFlat.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
namespace cont
|
namespace cont
|
||||||
@ -90,6 +93,36 @@ vtkm::cont::ArrayHandleConstant<T> make_ArrayHandleConstant(T value, vtkm::Id nu
|
|||||||
{
|
{
|
||||||
return vtkm::cont::ArrayHandleConstant<T>(value, numberOfValues);
|
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
|
} // vtkm::cont
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||||
|
|
||||||
|
#include <vtkm/Range.h>
|
||||||
#include <vtkm/TypeTraits.h>
|
#include <vtkm/TypeTraits.h>
|
||||||
#include <vtkm/VecTraits.h>
|
#include <vtkm/VecTraits.h>
|
||||||
|
|
||||||
@ -152,6 +153,52 @@ make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::
|
|||||||
{
|
{
|
||||||
return vtkm::cont::ArrayHandleCounting<CountingValueType>(start, step, length);
|
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
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#ifndef vtk_m_cont_ArrayHandleIndex_h
|
#ifndef vtk_m_cont_ArrayHandleIndex_h
|
||||||
#define vtk_m_cont_ArrayHandleIndex_h
|
#define vtk_m_cont_ArrayHandleIndex_h
|
||||||
|
|
||||||
|
#include <vtkm/Range.h>
|
||||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
@ -71,6 +72,29 @@ VTKM_CONT inline vtkm::cont::ArrayHandleIndex make_ArrayHandleIndex(vtkm::Id len
|
|||||||
{
|
{
|
||||||
return vtkm::cont::ArrayHandleIndex(length);
|
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
|
} // 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
|
} // namespace internal
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#ifndef vtk_m_cont_ArrayHandleUniformPointCoordinates_h
|
#ifndef vtk_m_cont_ArrayHandleUniformPointCoordinates_h
|
||||||
#define vtk_m_cont_ArrayHandleUniformPointCoordinates_h
|
#define vtk_m_cont_ArrayHandleUniformPointCoordinates_h
|
||||||
|
|
||||||
|
#include <vtkm/Range.h>
|
||||||
#include <vtkm/cont/ArrayExtractComponent.h>
|
#include <vtkm/cont/ArrayExtractComponent.h>
|
||||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||||
#include <vtkm/internal/ArrayPortalUniformPointCoordinates.h>
|
#include <vtkm/internal/ArrayPortalUniformPointCoordinates.h>
|
||||||
@ -83,6 +84,17 @@ struct VTKM_CONT_EXPORT ArrayExtractComponentImpl<vtkm::cont::StorageTagUniformP
|
|||||||
vtkm::CopyFlag allowCopy) const;
|
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
|
} // namespace internal
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,118 +12,16 @@
|
|||||||
|
|
||||||
#include <vtkm/TypeList.h>
|
#include <vtkm/TypeList.h>
|
||||||
|
|
||||||
namespace vtkm
|
#include <vtkm/cont/ArrayHandleBasic.h>
|
||||||
{
|
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
|
||||||
namespace cont
|
#include <vtkm/cont/ArrayHandleCompositeVector.h>
|
||||||
{
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||||
void ThrowArrayRangeComputeFailed()
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
{
|
#include <vtkm/cont/ArrayHandleSOA.h>
|
||||||
throw vtkm::cont::ErrorExecution("Failed to run ArrayRangeComputation on any device.");
|
#include <vtkm/cont/ArrayHandleStride.h>
|
||||||
}
|
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -152,7 +50,7 @@ struct ComputeRangeFunctor
|
|||||||
vtkm::cont::DeviceAdapterId device,
|
vtkm::cont::DeviceAdapterId device,
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range>& ranges) const
|
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
|
// Used with vtkm::ListForEach to get components
|
||||||
@ -172,7 +70,7 @@ struct ComputeRangeFunctor
|
|||||||
{
|
{
|
||||||
vtkm::cont::ArrayHandleStride<T> componentArray = array.ExtractComponent<T>(componentI);
|
vtkm::cont::ArrayHandleStride<T> componentArray = array.ExtractComponent<T>(componentI);
|
||||||
vtkm::cont::ArrayHandle<vtkm::Range> componentRange =
|
vtkm::cont::ArrayHandle<vtkm::Range> componentRange =
|
||||||
vtkm::cont::ArrayRangeCompute(componentArray, device);
|
vtkm::cont::ArrayRangeComputeTemplate(componentArray, device);
|
||||||
rangePortal.Set(componentI, componentRange.ReadPortal().Get(0));
|
rangePortal.Set(componentI, componentRange.ReadPortal().Get(0));
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
@ -191,6 +89,21 @@ vtkm::cont::ArrayHandle<vtkm::Range> ComputeForStorage(const vtkm::cont::Unknown
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // 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::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::UnknownArrayHandle& array,
|
||||||
vtkm::cont::DeviceAdapterId device)
|
vtkm::cont::DeviceAdapterId device)
|
||||||
{
|
{
|
||||||
@ -214,7 +127,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::Unknown
|
|||||||
{
|
{
|
||||||
vtkm::cont::ArrayHandleUniformPointCoordinates uniformPoints;
|
vtkm::cont::ArrayHandleUniformPointCoordinates uniformPoints;
|
||||||
array.AsArrayHandle(uniformPoints);
|
array.AsArrayHandle(uniformPoints);
|
||||||
return vtkm::cont::ArrayRangeCompute(uniformPoints, device);
|
return vtkm::cont::ArrayRangeComputeTemplate(uniformPoints, device);
|
||||||
}
|
}
|
||||||
using CartesianProductStorage =
|
using CartesianProductStorage =
|
||||||
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
|
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>())
|
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&)
|
catch (vtkm::cont::ErrorBadType&)
|
||||||
|
@ -31,7 +31,6 @@ namespace vtkm
|
|||||||
namespace cont
|
namespace cont
|
||||||
{
|
{
|
||||||
|
|
||||||
///@{
|
|
||||||
/// \brief Compute the range of the data in an array handle.
|
/// \brief Compute the range of the data in an array handle.
|
||||||
///
|
///
|
||||||
/// Given an `ArrayHandle`, this function computes the range (min and max) of
|
/// 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
|
/// Note that the ArrayRangeCompute.h header file contains only precompiled overloads
|
||||||
/// of ArrayRangeCompute. This is so that ArrayRangeCompute.h can be included in
|
/// 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
|
/// 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
|
/// for arbitrary `ArrayHandle`s not in this precompiled list, you need to use
|
||||||
/// ArrayRangeComputeTemplate.h. This contains a templated version of ArrayRangeCompute
|
/// `ArrayRangeComputeTemplate` (declared in `ArrayRangeComputeTemplate`), which
|
||||||
/// that will compile for any `ArrayHandle` type not already handled.
|
/// will compile for any `ArrayHandle` type not already handled.
|
||||||
///
|
///
|
||||||
|
|
||||||
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
VTKM_CONT_EXPORT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
||||||
const vtkm::cont::UnknownArrayHandle& array,
|
const vtkm::cont::UnknownArrayHandle& array,
|
||||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{});
|
||||||
|
|
||||||
#define VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T(T, Storage) \
|
namespace internal
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
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();
|
VTKM_CONT_EXPORT void ThrowArrayRangeComputeFailed();
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
VTKM_DEPRECATED(2.1, "Moved to vtkm::cont::internal.")
|
||||||
|
inline void ThrowArrayRangeComputeFailed()
|
||||||
|
{
|
||||||
|
internal::ThrowArrayRangeComputeFailed();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} // namespace vtkm::cont
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||||
|
|
||||||
#include <vtkm/BinaryOperators.h>
|
#include <vtkm/BinaryOperators.h>
|
||||||
|
#include <vtkm/Deprecated.h>
|
||||||
#include <vtkm/VecTraits.h>
|
#include <vtkm/VecTraits.h>
|
||||||
|
|
||||||
#include <vtkm/cont/Algorithm.h>
|
#include <vtkm/cont/Algorithm.h>
|
||||||
@ -42,8 +43,13 @@ struct ArrayRangeComputeFunctor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
|
||||||
template <typename T, typename S>
|
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,
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
||||||
vtkm::cont::DeviceAdapterId device)
|
vtkm::cont::DeviceAdapterId device)
|
||||||
{
|
{
|
||||||
@ -74,7 +80,7 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImpl(
|
|||||||
initial[1] = T(std::numeric_limits<CT>::lowest());
|
initial[1] = T(std::numeric_limits<CT>::lowest());
|
||||||
|
|
||||||
const bool rangeComputed = vtkm::cont::TryExecuteOnDevice(
|
const bool rangeComputed = vtkm::cont::TryExecuteOnDevice(
|
||||||
device, detail::ArrayRangeComputeFunctor{}, input, initial, result);
|
device, vtkm::cont::detail::ArrayRangeComputeFunctor{}, input, initial, result);
|
||||||
if (!rangeComputed)
|
if (!rangeComputed)
|
||||||
{
|
{
|
||||||
ThrowArrayRangeComputeFailed();
|
ThrowArrayRangeComputeFailed();
|
||||||
@ -93,17 +99,38 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImpl(
|
|||||||
return range;
|
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>
|
template <typename ArrayHandleType>
|
||||||
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
|
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeTemplate(
|
||||||
const ArrayHandleType& input,
|
const ArrayHandleType& input,
|
||||||
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny{})
|
||||||
{
|
{
|
||||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
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
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
@ -65,7 +65,6 @@ template <typename T, typename S>
|
|||||||
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array)
|
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||||
{
|
{
|
||||||
VerifyRange(array, vtkm::cont::ArrayRangeCompute(array));
|
VerifyRange(array, vtkm::cont::ArrayRangeCompute(array));
|
||||||
VerifyRange(array, vtkm::cont::ArrayRangeCompute(vtkm::cont::UnknownArrayHandle{ array }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
|
@ -576,7 +576,8 @@ template <typename FieldType>
|
|||||||
inline void ContourTreeMesh<FieldType>::ComputeMaxNeighbors()
|
inline void ContourTreeMesh<FieldType>::ComputeMaxNeighbors()
|
||||||
{
|
{
|
||||||
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
|
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);
|
this->MaxNeighbors = static_cast<vtkm::Id>(rangeArray.ReadPortal().Get(0).Max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleConstant.h>
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
||||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||||
#include <vtkm/cont/ArrayRangeCompute.h>
|
#include <vtkm/cont/ArrayRangeCompute.h>
|
||||||
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
|
|
||||||
#include <vtkm/cont/BitField.h>
|
#include <vtkm/cont/BitField.h>
|
||||||
#include <vtkm/cont/Invoker.h>
|
#include <vtkm/cont/Invoker.h>
|
||||||
#include <vtkm/cont/Logging.h>
|
#include <vtkm/cont/Logging.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user