Commit af14f583 authored by dpugmire's avatar dpugmire
Browse files

Merge branch 'master' of https://gitlab.kitware.com/vtk/vtk-m into messenger_cleanup

parents 55fff59e 8e757e58
......@@ -121,9 +121,11 @@ function(do_verify root_dir prefix)
cont/ArrayHandleVirtual.hxx
cont/ArrayHandleVirtualCoordinates.h
cont/CellLocator.h
cont/PointLocator.h
cont/StorageVirtual.h
cont/StorageVirtual.hxx
exec/CellLocator.h
exec/PointLocator.h
)
#by default every header in a testing directory doesn't need to be installed
......
# Create `ArrayHandleOffsetsToNumComponents`
`ArrayHandleOffsetsToNumComponents` is a fancy array that takes an array of
offsets and converts it to an array of the number of components for each
packed entry.
It is common in VTK-m to pack small vectors of variable sizes into a single
contiguous array. For example, cells in an explicit cell set can each have
a different amount of vertices (triangles = 3, quads = 4, tetra = 4, hexa =
8, etc.). Generally, to access items in this list, you need an array of
components in each entry and the offset for each entry. However, if you
have just the array of offsets in sorted order, you can easily derive the
number of components for each entry by subtracting adjacent entries. This
works best if the offsets array has a size that is one more than the number
of packed vectors with the first entry set to 0 and the last entry set to
the total size of the packed array (the offset to the end).
When packing data of this nature, it is common to start with an array that
is the number of components. You can convert that to an offsets array using
the `vtkm::cont::ConvertNumComponentsToOffsets` function. This will create
an offsets array with one extra entry as previously described. You can then
throw out the original number of components array and use the offsets with
`ArrayHandleOffsetsToNumComponents` to represent both the offsets and num
components while storing only one array.
This replaces the use of `ArrayHandleDecorator` in `CellSetExplicit`.
The two implementation should do the same thing, but the new
`ArrayHandleOffsetsToNumComponents` should be less complex for
compilers.
# `ArrayRangeCompute` works on any array type without compiling device code
Originally, `ArrayRangeCompute` required you to know specifically the
`ArrayHandle` type (value type and storage type) and to compile using any
device compiler. The method is changed to include only overloads that have
precompiled versions of `ArrayRangeCompute`.
Additionally, an `ArrayRangeCompute` overload that takes an
`UnknownArrayHandle` has been added. In addition to allowing you to compute
the range of arrays of unknown types, this implementation of
`ArrayRangeCompute` serves as a fallback for `ArrayHandle` types that are
not otherwise explicitly supported.
If you really want to make sure that you compute the range directly on an
`ArrayHandle` of a particular type, you can include
`ArrayRangeComputeTemplate.h`, which contains a templated overload of
`ArrayRangeCompute` that directly computes the range of an `ArrayHandle`.
Including this header requires compiling for device code.
......@@ -110,6 +110,7 @@ struct TypeTraits<const T> : TypeTraits<T>
VTKM_BASIC_REAL_TYPE(float)
VTKM_BASIC_REAL_TYPE(double)
VTKM_BASIC_INTEGER_TYPE(bool)
VTKM_BASIC_INTEGER_TYPE(char)
VTKM_BASIC_INTEGER_TYPE(signed char)
VTKM_BASIC_INTEGER_TYPE(unsigned char)
......
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_cont_ArrayHandleOffsetsToNumComponents_h
#define vtk_m_cont_ArrayHandleOffsetsToNumComponents_h
#include <vtkm/cont/ArrayHandle.h>
namespace vtkm
{
namespace internal
{
// Note that `ArrayPortalOffsetsToNumComponents` requires a source portal with +1 entry
// to avoid branching. See `ArrayHandleOffsetsToNumComponents` for details.
template <typename OffsetsPortal>
class VTKM_ALWAYS_EXPORT ArrayPortalOffsetsToNumComponents
{
OffsetsPortal Portal;
public:
ArrayPortalOffsetsToNumComponents() = default;
ArrayPortalOffsetsToNumComponents(const OffsetsPortal& portal)
: Portal(portal)
{
}
using ValueType = vtkm::IdComponent;
VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->Portal.GetNumberOfValues() - 1; }
VTKM_EXEC_CONT vtkm::IdComponent Get(vtkm::Id index) const
{
return static_cast<vtkm::IdComponent>(this->Portal.Get(index + 1) - this->Portal.Get(index));
}
};
}
} // namespace vtkm::internal
namespace vtkm
{
namespace cont
{
template <typename OffsetsStorageTag>
struct VTKM_ALWAYS_EXPORT StorageTagOffsetsToNumComponents
{
};
namespace internal
{
template <typename OffsetsStorageTag>
class VTKM_ALWAYS_EXPORT
Storage<vtkm::IdComponent, vtkm::cont::StorageTagOffsetsToNumComponents<OffsetsStorageTag>>
{
using OffsetsStorage = vtkm::cont::internal::Storage<vtkm::Id, OffsetsStorageTag>;
public:
using ReadPortalType =
vtkm::internal::ArrayPortalOffsetsToNumComponents<typename OffsetsStorage::ReadPortalType>;
// Writing to ArrayHandleOffsetsToNumComponents not really supported, but we need to define this.
using WritePortalType = ReadPortalType;
VTKM_CONT static constexpr vtkm::IdComponent GetNumberOfBuffers()
{
return OffsetsStorage::GetNumberOfBuffers();
}
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
{
vtkm::Id numOffsets = OffsetsStorage::GetNumberOfValues(buffers);
if (numOffsets < 1)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandleOffsetsToNumComponents requires an offsets array with at least one value.");
}
return numOffsets - 1;
}
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
vtkm::cont::internal::Buffer* buffers,
vtkm::CopyFlag,
vtkm::cont::Token&)
{
if (numValues == GetNumberOfValues(buffers))
{
// In general, we don't allow resizing of the array, but if it was "allocated" to the
// correct size, we will allow that.
}
else
{
throw vtkm::cont::ErrorBadAllocation(
"Cannot allocate/resize ArrayHandleOffsetsToNumComponents.");
}
}
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
VTKM_ASSERT(OffsetsStorage::GetNumberOfValues(buffers) > 0);
return ReadPortalType(OffsetsStorage::CreateReadPortal(buffers, device, token));
}
VTKM_CONT static WritePortalType CreateWritePortal(const vtkm::cont::internal::Buffer*,
vtkm::cont::DeviceAdapterId,
vtkm::cont::Token&)
{
throw vtkm::cont::ErrorBadAllocation("Cannot write to implicit arrays.");
}
};
} // namespace internal
/// \brief An `ArrayHandle` that converts an array of offsets to an array of `Vec` sizes.
///
/// It is common in VTK-m to pack small vectors of variable sizes into a single contiguous
/// array. For example, cells in an explicit cell set can each have a different amount of
/// vertices (triangles = 3, quads = 4, tetra = 4, hexa = 8, etc.). Generally, to access
/// items in this list, you need an array of components in each entry and the offset for
/// each entry. However, if you have just the array of offsets in sorted order, you can
/// easily derive the number of components for each entry by subtracting adjacent entries.
/// This works best if the offsets array has a size that is one more than the number of
/// packed vectors with the first entry set to 0 and the last entry set to the total size
/// of the packed array (the offset to the end).
///
/// `ArrayHandleOffsetsToNumComponents` decorates an array in exactly this manner. It
/// takes an offsets array and makes it behave like an array of counts. Note that the
/// offsets array must conform to the conditions described above: the offsets are in
/// sorted order and there is one additional entry in the offsets (ending in an offset
/// pointing past the end of the array).
///
/// When packing data of this nature, it is common to start with an array that is the
/// number of components. You can convert that to an offsets array using the
/// `vtkm::cont::ConvertNumComponentsToOffsets` function. This will create an offsets array
/// with one extra entry as previously described. You can then throw out the original
/// number of components array and use the offsets with `ArrayHandleOffsetsToNumComponents`
/// to represent both the offsets and num components while storing only one array.
///
template <class OffsetsArray>
class VTKM_ALWAYS_EXPORT ArrayHandleOffsetsToNumComponents
: public vtkm::cont::ArrayHandle<
vtkm::IdComponent,
vtkm::cont::StorageTagOffsetsToNumComponents<typename OffsetsArray::StorageTag>>
{
VTKM_IS_ARRAY_HANDLE(OffsetsArray);
VTKM_STATIC_ASSERT_MSG((std::is_same<typename OffsetsArray::ValueType, vtkm::Id>::value),
"Offsets array must have a value type of vtkm::Id.");
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleOffsetsToNumComponents,
(ArrayHandleOffsetsToNumComponents<OffsetsArray>),
(vtkm::cont::ArrayHandle<
vtkm::IdComponent,
vtkm::cont::StorageTagOffsetsToNumComponents<typename OffsetsArray::StorageTag>>));
VTKM_CONT ArrayHandleOffsetsToNumComponents(const OffsetsArray& array)
: Superclass(array.GetBuffers())
{
}
};
template <typename OffsetsStorageTag>
VTKM_CONT vtkm::cont::ArrayHandleOffsetsToNumComponents<
vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>>
make_ArrayHandleOffsetsToNumComponents(
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& array)
{
// Converts to correct type.
return array;
}
}
} // namespace vtkm::cont
#endif //vtk_m_cont_ArrayHandleOffsetsToNumComponents_h
......@@ -10,6 +10,8 @@
#include <vtkm/cont/ArrayRangeComputeTemplate.h>
#include <vtkm/TypeList.h>
namespace vtkm
{
namespace cont
......@@ -78,6 +80,8 @@ 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);
......@@ -111,7 +115,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
return rangeArray;
}
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>& input,
vtkm::cont::DeviceAdapterId)
{
......@@ -120,5 +124,129 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
result.WritePortal().Set(0, vtkm::Range(0, input.GetNumberOfValues() - 1));
return result;
}
namespace
{
using AllScalars = vtkm::TypeListBaseC;
template <typename vtkm::IdComponent N>
struct VecTransform
{
template <typename T>
using type = vtkm::Vec<T, N>;
};
template <vtkm::IdComponent N>
using AllVecOfSize = vtkm::ListTransform<AllScalars, VecTransform<N>::template type>;
using AllVec = vtkm::ListAppend<AllVecOfSize<2>, AllVecOfSize<3>, AllVecOfSize<4>>;
using AllTypes = vtkm::ListAppend<AllScalars, AllVec>;
struct ComputeRangeFunctor
{
// Used with UnknownArrayHandle::CastAndCallForTypes
template <typename T, typename S>
void operator()(const vtkm::cont::ArrayHandle<T, S>& array,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::ArrayHandle<vtkm::Range>& ranges) const
{
ranges = vtkm::cont::ArrayRangeCompute(array, device);
}
// Used with vtkm::ListForEach to get components
template <typename T>
void operator()(T,
const vtkm::cont::UnknownArrayHandle& array,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::ArrayHandle<vtkm::Range>& ranges,
bool& success) const
{
if (!success && array.IsBaseComponentType<T>())
{
vtkm::IdComponent numComponents = array.GetNumberOfComponentsFlat();
ranges.Allocate(numComponents);
auto rangePortal = ranges.WritePortal();
for (vtkm::IdComponent componentI = 0; componentI < numComponents; ++componentI)
{
vtkm::cont::ArrayHandleStride<T> componentArray = array.ExtractComponent<T>(componentI);
vtkm::cont::ArrayHandle<vtkm::Range> componentRange =
vtkm::cont::ArrayRangeCompute(componentArray, device);
rangePortal.Set(componentI, componentRange.ReadPortal().Get(0));
}
success = true;
}
}
};
template <typename TList, typename Storage>
vtkm::cont::ArrayHandle<vtkm::Range> ComputeForStorage(const vtkm::cont::UnknownArrayHandle& array,
vtkm::cont::DeviceAdapterId device)
{
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
array.CastAndCallForTypes<TList, vtkm::List<Storage>>(ComputeRangeFunctor{}, device, ranges);
return ranges;
}
} // anonymous namespace
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::UnknownArrayHandle& array,
vtkm::cont::DeviceAdapterId device)
{
// First, try fast-paths of precompiled array types common(ish) in fields.
try
{
if (array.IsStorageType<vtkm::cont::StorageTagBasic>())
{
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagBasic>(array, device);
}
if (array.IsStorageType<vtkm::cont::StorageTagSOA>())
{
return ComputeForStorage<AllVec, vtkm::cont::StorageTagSOA>(array, device);
}
if (array.IsStorageType<vtkm::cont::StorageTagXGCCoordinates>())
{
return ComputeForStorage<vtkm::TypeListFieldScalar, vtkm::cont::StorageTagXGCCoordinates>(
array, device);
}
if (array.IsStorageType<vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag>())
{
vtkm::cont::ArrayHandleUniformPointCoordinates uniformPoints;
array.AsArrayHandle(uniformPoints);
return vtkm::cont::ArrayRangeCompute(uniformPoints, device);
}
using CartesianProductStorage =
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagBasic>;
if (array.IsStorageType<CartesianProductStorage>())
{
return ComputeForStorage<vtkm::TypeListFieldScalar, CartesianProductStorage>(array, device);
}
if (array.IsStorageType<vtkm::cont::StorageTagConstant>())
{
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagConstant>(array, device);
}
if (array.IsStorageType<vtkm::cont::StorageTagCounting>())
{
return ComputeForStorage<AllTypes, vtkm::cont::StorageTagCounting>(array, device);
}
if (array.IsStorageType<vtkm::cont::StorageTagIndex>())
{
return ArrayRangeCompute(array.AsArrayHandle<vtkm::cont::ArrayHandleIndex>(), device);
}
}
catch (vtkm::cont::ErrorBadValue&)
{
// If a cast/call failed, try falling back to a more general implementation.
}
vtkm::cont::ArrayHandle<vtkm::Range> ranges;
bool success = false;
vtkm::ListForEach(ComputeRangeFunctor{}, AllScalars{}, array, device, ranges, success);
return ranges;
}
}
} // namespace vtkm::cont
......@@ -20,9 +20,11 @@
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandleSOA.h>
#include <vtkm/cont/ArrayHandleStride.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleXGCCoordinates.h>
#include <vtkm/cont/DeviceAdapterTag.h>
#include <vtkm/cont/UnknownArrayHandle.h>
namespace vtkm
{
......@@ -51,6 +53,10 @@ namespace cont
/// that 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 \
......@@ -104,6 +110,8 @@ 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);
......@@ -117,25 +125,6 @@ VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComput
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag>& array,
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
// Implementation of composite vectors
VTKM_CONT_EXPORT
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandle<vtkm::Vec3f_32,
typename vtkm::cont::ArrayHandleCompositeVector<
vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>>::StorageTag>& input,
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandle<vtkm::Vec3f_64,
typename vtkm::cont::ArrayHandleCompositeVector<
vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>>::StorageTag>& input,
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(
......@@ -204,7 +193,7 @@ VTKM_CONT inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
if (portal.GetNumberOfValues() > 0)
{
T first = input.ReadPortal().Get(0);
T last = input.ReadPortal().Get(portal.GetNumberOfValues() - 1);
T last = input.ReadPortal().Get(input.GetNumberOfValues() - 1);
for (vtkm::IdComponent cIndex = 0; cIndex < Traits::NUM_COMPONENTS; ++cIndex)
{
auto firstComponent = Traits::GetComponent(first, cIndex);
......@@ -226,7 +215,7 @@ VTKM_CONT inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
}
// Implementation of index arrays
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
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{});
///@}
......
......@@ -30,6 +30,7 @@ set(headers
ArrayHandleImplicit.h
ArrayHandleIndex.h
ArrayHandleMultiplexer.h
ArrayHandleOffsetsToNumComponents.h
ArrayHandlePermutation.h
ArrayHandleRecombineVec.h
ArrayHandleReverse.h
......@@ -104,7 +105,6 @@ set(headers
Logging.h
ParticleArrayCopy.h
PartitionedDataSet.h
PointLocator.h
PointLocatorUniformGrid.h
PointLocatorSparseGrid.h
RuntimeDeviceInformation.h
......@@ -183,7 +183,6 @@ set(device_sources
FieldRangeCompute.cxx
FieldRangeGlobalCompute.cxx
PartitionedDataSet.cxx
PointLocator.cxx
PointLocatorSparseGrid.cxx
RuntimeDeviceInformation.cxx
Timer.cxx
......@@ -195,6 +194,7 @@ if (NOT VTKm_NO_DEPRECATED_VIRTUAL)
ArrayHandleVirtual.h
ArrayHandleVirtualCoordinates.h
CellLocator.h
PointLocator.h
StorageVirtual.h
)
......@@ -206,6 +206,7 @@ if (NOT VTKm_NO_DEPRECATED_VIRTUAL)
set(device_sources ${device_sources}
ArrayHandleVirtual.cxx
CellLocator.cxx
PointLocator.cxx
StorageVirtual.cxx
)
endif()
......
......@@ -16,7 +16,7 @@
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleDecorator.h>
#include <vtkm/cont/ArrayHandleOffsetsToNumComponents.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
#include <vtkm/exec/ConnectivityExplicit.h>
......@@ -37,32 +37,6 @@ struct CellSetExplicitConnectivityChooser
using ConnectivityType = vtkm::cont::internal::ConnectivityExplicitInternals<>;
};
// Used with ArrayHandleDecorator to recover the NumIndices array from the
// offsets.
struct NumIndicesDecorator
{
template <typename OffsetsPortal>
struct Functor
{
OffsetsPortal Offsets;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::IdComponent operator()(vtkm::Id cellId) const
{
return static_cast<vtkm::IdComponent>(this->Offsets.Get(cellId + 1) -
this->Offsets.Get(cellId));
}
};
template <typename OffsetsPortal>
static VTKM_CONT Functor<typename std::decay<OffsetsPortal>::type> CreateFunctor(
OffsetsPortal&& portal)
{
return { std::forward<OffsetsPortal>(portal) };
}
};
} // namespace detail
#ifndef VTKM_DEFAULT_SHAPES_STORAGE_TAG
......@@ -142,8 +116,7 @@ class VTKM_ALWAYS_EXPORT CellSetExplicit : public CellSet
using ConnectivityArrayType = typename ConnectivityType::ConnectivityArrayType;
using OffsetsArrayType = typename ConnectivityType::OffsetsArrayType;
using NumIndicesArrayType =
vtkm::cont::ArrayHandleDecorator<detail::NumIndicesDecorator, OffsetsArrayType>;
using NumIndicesArrayType = vtkm::cont::ArrayHandleOffsetsToNumComponents<OffsetsArrayType>;
using ExecConnectivityType =
vtkm::exec::ConnectivityExplicit<typename ShapesArrayType::ReadPortalType,
......
......@@ -14,7 +14,6 @@
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayGetValues.h>
#include <vtkm/cont/ArrayHandleDecorator.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/TryExecute.h>
......@@ -442,11 +441,8 @@ auto CellSetExplicit<SST, CST, OST>
-> typename ConnectivityChooser<VisitTopology,
IncidentTopology>::NumIndicesArrayType
{
auto offsets = this->GetOffsetsArray(visited, incident);
const vtkm::Id numVals = offsets.GetNumberOfValues() - 1;
return vtkm::cont::make_ArrayHandleDecorator(numVals,
detail::NumIndicesDecorator{},
std::move(offsets));
// Converts to NumIndicesArrayType (which is an ArrayHandleOffsetsToNumComponents)
return this->GetOffsetsArray(visited, incident);
}
//----------------------------------------------------------------------------
......
......@@ -8,6 +8,7 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/CoordinateSystem.h>
......