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
|
||||
|
||||
#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
|
||||
|
||||
|
@ -65,7 +65,6 @@ template <typename T, typename S>
|
||||
void CheckRange(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||
{
|
||||
VerifyRange(array, vtkm::cont::ArrayRangeCompute(array));
|
||||
VerifyRange(array, vtkm::cont::ArrayRangeCompute(vtkm::cont::UnknownArrayHandle{ array }));
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
|
@ -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