Add ArrayGetValues specilization for ArrayHandleCast

ArrayGetValues for ArrayHandleCast needs to be handled specially as an
`UnknownArrayHandle::IsBaseComponentType` check inside the implementation
gives unexpected results for ArrayHandleCast.

With this fix, the values are first copied from the source array type and
then casted to the appropriate type before returning.
This commit is contained in:
Sujin Philip 2021-11-08 14:37:49 -05:00
parent 845ca21ebc
commit 4a37e02ffe
2 changed files with 31 additions and 1 deletions

@ -103,6 +103,30 @@ VTKM_CONT void ArrayGetValues(const vtkm::cont::ArrayHandle<vtkm::Id, SIds>& ids
internal::ArrayGetValuesImpl(ids, data, output);
}
/// We need a specialization for `ArrayHandleCasts` to avoid runtime type missmatch errors inside
/// `ArrayGetValuesImpl`.
template <typename SIds, typename TIn, typename SData, typename TOut, typename SOut>
VTKM_CONT void ArrayGetValues(
const vtkm::cont::ArrayHandle<vtkm::Id, SIds>& ids,
const vtkm::cont::ArrayHandle<TOut, vtkm::cont::StorageTagCast<TIn, SData>>& data,
vtkm::cont::ArrayHandle<TOut, SOut>& output)
{
// In this specialization, we extract the values from the cast array's source array and
// then cast and copy to output.
vtkm::cont::ArrayHandleBasic<TIn> tempOutput;
vtkm::cont::ArrayHandleCast<TOut, vtkm::cont::ArrayHandle<TIn, SData>> castArray = data;
ArrayGetValues(ids, castArray.GetSourceArray(), tempOutput);
vtkm::Id numExtracted = tempOutput.GetNumberOfValues();
output.Allocate(numExtracted);
auto inp = tempOutput.ReadPortal();
auto outp = output.WritePortal();
for (vtkm::Id i = 0; i < numExtracted; ++i)
{
outp.Set(i, static_cast<TOut>(inp.Get(i)));
}
}
template <typename SIds, typename T, typename SData, typename Alloc>
VTKM_CONT void ArrayGetValues(const vtkm::cont::ArrayHandle<vtkm::Id, SIds>& ids,
const vtkm::cont::ArrayHandle<T, SData>& data,

@ -10,6 +10,7 @@
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayGetValues.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/testing/Testing.h>
@ -68,6 +69,12 @@ void TryCopy()
vtkm::cont::ArrayGetValues(ids, data, output);
TestValues<ValueType>(output, { 3, 8, 7 });
}
{ // Test the specialization for ArrayHandleCast
auto castedData = vtkm::cont::make_ArrayHandleCast<vtkm::Float64>(data);
vtkm::cont::ArrayHandle<vtkm::Float64> output;
vtkm::cont::ArrayGetValues(ids, castedData, output);
TestValues<vtkm::Float64>(output, { 3.0, 8.0, 7.0 });
}
}
{ // vector ids
@ -125,7 +132,6 @@ void TryCopy()
}
}
{ // single values
{
const ValueType output = vtkm::cont::ArrayGetValue(8, data);