Fix new instances of ArrayHandleRuntimeVec in UnknownArrayHandle

`UnknownArrayHandle` is supposed to treat `ArrayHandleRuntimeVec` the
same as `ArrayHandleBasic`. However, the `NewInstance` methods were
failing because they need custom handling of the vec size.
This commit is contained in:
Kenneth Moreland 2023-04-19 11:14:05 -06:00
parent 70f8fee958
commit 3c1afe53dc
3 changed files with 67 additions and 0 deletions

@ -0,0 +1,8 @@
# Fix new instances of ArrayHandleRuntimeVec in UnknownArrayHandle
`UnknownArrayHandle` is supposed to treat `ArrayHandleRuntimeVec` the same
as `ArrayHandleBasic`. However, the `NewInstance` methods were failing
because they need custom handling of the vec size. Special cases in the
`UnknownArrayHandle::NewInstance*()` methods have been added to fix this
problem.

@ -177,6 +177,16 @@ VTKM_CONT bool UnknownArrayHandle::IsValid() const
VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstance() const
{
if (this->IsStorageType<vtkm::cont::StorageTagRuntimeVec>())
{
// Special case for `ArrayHandleRuntimeVec`, which (1) can be used in place of
// a basic array in `UnknownArrayHandle` and (2) needs a special construction to
// capture the correct number of components. Also note that we are allowing this
// special case to be implemented in `NewInstanceBasic` because it has a better
// fallback (throw an exception rather than create a potentially incompatible
// with the wrong number of components).
return this->NewInstanceBasic();
}
UnknownArrayHandle newArray;
if (this->Container)
{
@ -188,6 +198,25 @@ VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstance() const
VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceBasic() const
{
UnknownArrayHandle newArray;
if (this->IsStorageType<vtkm::cont::StorageTagRuntimeVec>())
{
// Special case for `ArrayHandleRuntimeVec`, which (1) can be used in place of
// a basic array in `UnknownArrayHandle` and (2) needs a special construction to
// capture the correct number of components.
auto runtimeVecArrayCreator = [&](auto exampleComponent) {
using ComponentType = decltype(exampleComponent);
if (this->IsBaseComponentType<ComponentType>())
{
newArray =
vtkm::cont::make_ArrayHandleRuntimeVec<ComponentType>(this->GetNumberOfComponentsFlat());
}
};
vtkm::ListForEach(runtimeVecArrayCreator, vtkm::TypeListBaseC{});
if (newArray.IsValid())
{
return newArray;
}
}
if (this->Container)
{
newArray.Container = this->Container->NewInstanceBasic();
@ -197,6 +226,14 @@ VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceBasic() const
VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceFloatBasic() const
{
if (this->IsStorageType<vtkm::cont::StorageTagRuntimeVec>())
{
// Special case for `ArrayHandleRuntimeVec`, which (1) can be used in place of
// a basic array in `UnknownArrayHandle` and (2) needs a special construction to
// capture the correct number of components.
return vtkm::cont::make_ArrayHandleRuntimeVec<vtkm::FloatDefault>(
this->GetNumberOfComponentsFlat());
}
UnknownArrayHandle newArray;
if (this->Container)
{

@ -11,6 +11,7 @@
#include <vtkm/cont/UncertainArrayHandle.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
@ -574,6 +575,27 @@ void TryConvertRuntimeVec()
VTKM_TEST_ASSERT(unknownWithRuntimeVec.CanConvert<BasicArrayType>());
BasicArrayType outputArray = unknownWithRuntimeVec.AsArrayHandle<BasicArrayType>();
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, outputArray));
std::cout << " Copy ArrayHandleRuntimeVec to a new instance" << std::endl;
vtkm::cont::UnknownArrayHandle unknownCopy = unknownWithRuntimeVec.NewInstance();
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
unknownCopy.GetNumberOfComponentsFlat());
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
std::cout << " Copy ArrayHandleRuntimeVec as basic array" << std::endl;
unknownCopy = unknownWithRuntimeVec.NewInstanceBasic();
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
unknownCopy.GetNumberOfComponentsFlat());
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
std::cout << " Copy ArrayHandleRuntimeVec to float array" << std::endl;
unknownCopy = unknownWithRuntimeVec.NewInstanceFloatBasic();
VTKM_TEST_ASSERT(unknownWithRuntimeVec.GetNumberOfComponentsFlat() ==
unknownCopy.GetNumberOfComponentsFlat());
vtkm::cont::ArrayCopy(unknownWithRuntimeVec, unknownCopy);
VTKM_TEST_ASSERT(test_equal_ArrayHandles(inputArray, unknownCopy));
}
void TryConvertRuntimeVec()