mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Add support for getting vec sizes of unknown arrays when runtime selected
The `GetNumberOfComponents` and `GetNumberOfComponentsFlat` methods in `UnknownArrayHandle` have been updated to correctly report the number of components in special `ArrayHandle`s where the `Vec` sizes of the values are not selected until runtime. Previously, these methods always reported 0 because the value type could not report the size of the `Vec`. The lookup has been modified to query the `ArrayHandle`'s `Storage` for the number of components where supported. Note that this only works on `Storage` that provides a method to get the runtime `Vec` size. If that is not provided, as will be the case if the number of components can vary from one value to the next, it will still report 0. This feature is implemented by looking for a method named `GetNumberOfComponents` is the `Storage` class for the `ArrayHandle`. If this method is found, it is used to query the size at runtime.
This commit is contained in:
parent
a4517e70b0
commit
a80de8019a
18
docs/changelog/unknownarray-runtime-components.md
Normal file
18
docs/changelog/unknownarray-runtime-components.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Added support for getting vec sizes of unknown arrays when runtime selected
|
||||
|
||||
The `GetNumberOfComponents` and `GetNumberOfComponentsFlat` methods in
|
||||
`UnknownArrayHandle` have been updated to correctly report the number of
|
||||
components in special `ArrayHandle`s where the `Vec` sizes of the values
|
||||
are not selected until runtime.
|
||||
|
||||
Previously, these methods always reported 0 because the value type could
|
||||
not report the size of the `Vec`. The lookup has been modified to query the
|
||||
`ArrayHandle`'s `Storage` for the number of components where supported.
|
||||
Note that this only works on `Storage` that provides a method to get the
|
||||
runtime `Vec` size. If that is not provided, as will be the case if the
|
||||
number of components can vary from one value to the next, it will still
|
||||
report 0.
|
||||
|
||||
This feature is implemented by looking for a method named
|
||||
`GetNumberOfComponents` is the `Storage` class for the `ArrayHandle`. If
|
||||
this method is found, it is used to query the size at runtime.
|
@ -437,7 +437,7 @@ public:
|
||||
using ReadPortalType = vtkm::internal::ArrayPortalRecombineVec<ReadWritePortal>;
|
||||
using WritePortalType = vtkm::internal::ArrayPortalRecombineVec<ReadWritePortal>;
|
||||
|
||||
VTKM_CONT static vtkm::IdComponent NumberOfComponents(
|
||||
VTKM_CONT static vtkm::IdComponent GetNumberOfComponents(
|
||||
const std::vector<vtkm::cont::internal::Buffer>& buffers)
|
||||
{
|
||||
return static_cast<vtkm::IdComponent>(
|
||||
@ -455,7 +455,7 @@ public:
|
||||
vtkm::CopyFlag preserve,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
|
||||
vtkm::IdComponent numComponents = GetNumberOfComponents(buffers);
|
||||
for (vtkm::IdComponent component = 0; component < numComponents; ++component)
|
||||
{
|
||||
SourceStorage::ResizeBuffers(
|
||||
@ -477,7 +477,7 @@ public:
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
|
||||
vtkm::IdComponent numComponents = GetNumberOfComponents(buffers);
|
||||
|
||||
// The array portal needs a runtime-allocated array of portals for each component.
|
||||
// We use the vtkm::cont::internal::Buffer object to allow us to allocate memory on the
|
||||
@ -515,7 +515,7 @@ public:
|
||||
vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token)
|
||||
{
|
||||
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
|
||||
vtkm::IdComponent numComponents = GetNumberOfComponents(buffers);
|
||||
|
||||
// The array portal needs a runtime-allocated array of portals for each component.
|
||||
// We use the vtkm::cont::internal::Buffer object to allow us to allocate memory on the
|
||||
@ -608,7 +608,7 @@ private:
|
||||
public:
|
||||
vtkm::IdComponent GetNumberOfComponents() const
|
||||
{
|
||||
return StorageType::NumberOfComponents(this->GetBuffers());
|
||||
return StorageType::GetNumberOfComponents(this->GetBuffers());
|
||||
}
|
||||
|
||||
vtkm::cont::ArrayHandleStride<ComponentType> GetComponentArray(
|
||||
|
@ -265,7 +265,7 @@ vtkm::IdComponent UnknownArrayHandle::GetNumberOfComponents() const
|
||||
{
|
||||
if (this->Container)
|
||||
{
|
||||
return this->Container->NumberOfComponents();
|
||||
return this->Container->NumberOfComponents(this->Container->ArrayHandlePointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -277,7 +277,7 @@ VTKM_CONT vtkm::IdComponent UnknownArrayHandle::GetNumberOfComponentsFlat() cons
|
||||
{
|
||||
if (this->Container)
|
||||
{
|
||||
return this->Container->NumberOfComponentsFlat();
|
||||
return this->Container->NumberOfComponentsFlat(this->Container->ArrayHandlePointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -56,49 +56,88 @@ vtkm::Id UnknownAHNumberOfValues(void* mem)
|
||||
return arrayHandle->GetNumberOfValues();
|
||||
}
|
||||
|
||||
template <typename T, typename StaticSize = typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic>
|
||||
struct UnknownAHNumberOfComponentsImpl;
|
||||
template <typename T>
|
||||
struct UnknownAHNumberOfComponentsImpl<T, vtkm::VecTraitsTagSizeStatic>
|
||||
// Uses SFINAE to use Storage<>::GetNumberOfComponents if it exists, or the VecTraits otherwise
|
||||
template <typename T, typename S>
|
||||
inline auto UnknownAHNumberOfComponentsImpl(void* mem)
|
||||
-> decltype(vtkm::cont::internal::Storage<T, S>::GetNumberOfComponents(
|
||||
std::vector<vtkm::cont::internal::Buffer>()))
|
||||
{
|
||||
static constexpr vtkm::IdComponent Value = vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS;
|
||||
};
|
||||
template <typename T>
|
||||
struct UnknownAHNumberOfComponentsImpl<T, vtkm::VecTraitsTagSizeVariable>
|
||||
{
|
||||
static constexpr vtkm::IdComponent Value = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
vtkm::IdComponent UnknownAHNumberOfComponents()
|
||||
{
|
||||
return UnknownAHNumberOfComponentsImpl<T>::Value;
|
||||
using AH = vtkm::cont::ArrayHandle<T, S>;
|
||||
AH* arrayHandle = reinterpret_cast<AH*>(mem);
|
||||
return vtkm::cont::internal::Storage<T, S>::GetNumberOfComponents(arrayHandle->GetBuffers());
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename = typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic,
|
||||
typename = vtkm::HasVecTraits<T>>
|
||||
struct UnknownAHNumberOfComponentsFlatImpl;
|
||||
template <typename T>
|
||||
struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeStatic, std::true_type>
|
||||
// Uses SFINAE to use the number of compnents in VecTraits.
|
||||
// Note that this will conflict with the above overloaded function if the storage has a
|
||||
// GetNumberOfComponents method and VecTraits has a static size. However, I cannot think
|
||||
// of a use case for the storage to report the number of components for a static data type.
|
||||
// If that happens, this implementation will need to be modified.
|
||||
template <typename T, typename S>
|
||||
inline auto UnknownAHNumberOfComponentsImpl(void*)
|
||||
-> decltype(vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS)
|
||||
{
|
||||
static constexpr vtkm::IdComponent Value = vtkm::VecFlat<T>::NUM_COMPONENTS;
|
||||
};
|
||||
template <typename T>
|
||||
struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeVariable, std::true_type>
|
||||
{
|
||||
static constexpr vtkm::IdComponent Value = 0;
|
||||
};
|
||||
template <typename T>
|
||||
struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeStatic, std::false_type>
|
||||
{
|
||||
static constexpr vtkm::IdComponent Value = 1;
|
||||
};
|
||||
static constexpr vtkm::IdComponent numComponents =
|
||||
vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS;
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
vtkm::IdComponent UnknownAHNumberOfComponentsFlat()
|
||||
// Fallback for when there is no way to determine the number of components. (This could be
|
||||
// because each value could have a different number of components.
|
||||
template <typename T, typename S>
|
||||
inline vtkm::IdComponent UnknownAHNumberOfComponentsImpl(...)
|
||||
{
|
||||
return UnknownAHNumberOfComponentsFlatImpl<T>::Value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::IdComponent UnknownAHNumberOfComponents(void* mem)
|
||||
{
|
||||
return UnknownAHNumberOfComponentsImpl<T, S>(mem);
|
||||
}
|
||||
|
||||
// Uses SFINAE to use Storage<>::GetNumberOfComponents if it exists, or the VecTraits otherwise
|
||||
template <typename T, typename S>
|
||||
inline auto UnknownAHNumberOfComponentsFlatImpl(void* mem)
|
||||
-> decltype(vtkm::cont::internal::Storage<T, S>::GetNumberOfComponents(
|
||||
std::vector<vtkm::cont::internal::Buffer>()))
|
||||
{
|
||||
using AH = vtkm::cont::ArrayHandle<T, S>;
|
||||
AH* arrayHandle = reinterpret_cast<AH*>(mem);
|
||||
// Making an assumption here that `T` is a `Vec`-like object that `GetNumberOfComponents`
|
||||
// will report on how many each has. Further assuming that the components of `T` are
|
||||
// static. If a future `ArrayHandle` type violates this, this code will have to become
|
||||
// more complex.
|
||||
return (vtkm::cont::internal::Storage<T, S>::GetNumberOfComponents(arrayHandle->GetBuffers()) *
|
||||
vtkm::VecFlat<typename vtkm::internal::SafeVecTraits<T>::ComponentType>::NUM_COMPONENTS);
|
||||
}
|
||||
|
||||
// Uses SFINAE to use the number of compnents in VecTraits.
|
||||
// Note that this will conflict with the above overloaded function if the storage has a
|
||||
// GetNumberOfComponents method and VecTraits has a static size. However, I cannot think
|
||||
// of a use case for the storage to report the number of components for a static data type.
|
||||
// If that happens, this implementation will need to be modified.
|
||||
template <typename T, typename S>
|
||||
inline auto UnknownAHNumberOfComponentsFlatImpl(void*)
|
||||
-> decltype(vtkm::VecTraits<T>::NUM_COMPONENTS)
|
||||
{
|
||||
// static constexpr vtkm::IdComponent numComponents = vtkm::VecFlat<T>::NUM_COMPONENTS;
|
||||
// return numComponents;
|
||||
return vtkm::VecFlat<T>::NUM_COMPONENTS;
|
||||
}
|
||||
|
||||
// Fallback for when there is no way to determine the number of components. (This could be
|
||||
// because each value could have a different number of components or just that VecTraits
|
||||
// are not defined.) Since it cannot be flattened, just return the same as num components.
|
||||
template <typename T, typename S>
|
||||
inline vtkm::IdComponent UnknownAHNumberOfComponentsFlatImpl(...)
|
||||
{
|
||||
return UnknownAHNumberOfComponentsImpl<T, S>(static_cast<void*>(nullptr));
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
vtkm::IdComponent UnknownAHNumberOfComponentsFlat(void* mem)
|
||||
{
|
||||
return UnknownAHNumberOfComponentsFlatImpl<T, S>(mem);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
@ -230,7 +269,7 @@ struct VTKM_CONT_EXPORT UnknownAHContainer
|
||||
using NumberOfValuesType = vtkm::Id(void*);
|
||||
NumberOfValuesType* NumberOfValues;
|
||||
|
||||
using NumberOfComponentsType = vtkm::IdComponent();
|
||||
using NumberOfComponentsType = vtkm::IdComponent(void*);
|
||||
NumberOfComponentsType* NumberOfComponents;
|
||||
NumberOfComponentsType* NumberOfComponentsFlat;
|
||||
|
||||
@ -348,8 +387,8 @@ inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S
|
||||
, NewInstanceBasic(detail::UnknownAHNewInstanceBasic<T>)
|
||||
, NewInstanceFloatBasic(detail::UnknownAHNewInstanceFloatBasic<T>)
|
||||
, NumberOfValues(detail::UnknownAHNumberOfValues<T, S>)
|
||||
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T>)
|
||||
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T>)
|
||||
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T, S>)
|
||||
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T, S>)
|
||||
, Allocate(detail::UnknownAHAllocate<T, S>)
|
||||
, ShallowCopy(detail::UnknownAHShallowCopy<T, S>)
|
||||
, DeepCopy(detail::UnknownAHDeepCopy<T, S>)
|
||||
|
Loading…
Reference in New Issue
Block a user