mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-08 03:18:58 +00:00
Merge topic 'new-instance-variable-components'
4d02add0e Enable new instances of unknown arrays with dynamic sizes Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3150
This commit is contained in:
commit
e27573cca9
16
docs/changelog/new-instance-variable-components.md
Normal file
16
docs/changelog/new-instance-variable-components.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Enable new instances of unknown arrays with dynamic sizes
|
||||
|
||||
`UnknownArrayHandle` allows you to create a new instance of a compatible
|
||||
array so that when receiving an array of unknown type, a place to put the
|
||||
output can be created. However, these methods only worked if the number of
|
||||
components in each value could be determined statically at compile time.
|
||||
|
||||
However, there are some special `ArrayHandle`s that can define the number
|
||||
of components at runtime. In this case, the `ArrayHandle` would throw an
|
||||
exception if `NewInstanceBasic` or `NewInstanceFloatBasic` was called.
|
||||
|
||||
Although rare, this condition could happen when, for example, an array was
|
||||
extracted from an `UnknownArrayHandle` with `ExtractArrayFromComponents` or
|
||||
with `CastAndCallWithExtractedArray` and then the resulting array was
|
||||
passed to a function with arrays passed with `UnknownArrayHandle` such as
|
||||
`ArrayCopy`.
|
@ -219,7 +219,7 @@ VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceBasic() const
|
||||
}
|
||||
if (this->Container)
|
||||
{
|
||||
newArray.Container = this->Container->NewInstanceBasic();
|
||||
newArray.Container = this->Container->NewInstanceBasic(this->Container->ArrayHandlePointer);
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
@ -237,7 +237,8 @@ VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceFloatBasic() const
|
||||
UnknownArrayHandle newArray;
|
||||
if (this->Container)
|
||||
{
|
||||
newArray.Container = this->Container->NewInstanceFloatBasic();
|
||||
newArray.Container =
|
||||
this->Container->NewInstanceFloatBasic(this->Container->ArrayHandlePointer);
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ struct VTKM_CONT_EXPORT UnknownAHContainer
|
||||
using NewInstanceType = void*();
|
||||
NewInstanceType* NewInstance;
|
||||
|
||||
using NewInstanceBasicType = std::shared_ptr<UnknownAHContainer>();
|
||||
using NewInstanceBasicType = std::shared_ptr<UnknownAHContainer>(void*);
|
||||
NewInstanceBasicType* NewInstanceBasic;
|
||||
NewInstanceBasicType* NewInstanceFloatBasic;
|
||||
|
||||
@ -307,39 +307,56 @@ private:
|
||||
explicit UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S>& array);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeStatic)
|
||||
template <typename T, typename S>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(void*, vtkm::VecTraitsTagSizeStatic)
|
||||
{
|
||||
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<T>{});
|
||||
}
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeVariable)
|
||||
template <typename T, typename S>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(void* mem,
|
||||
vtkm::VecTraitsTagSizeVariable)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Cannot create a basic array container from with ValueType of " +
|
||||
vtkm::IdComponent numComponents = UnknownAHNumberOfComponentsFlat<T, S>(mem);
|
||||
if (numComponents < 1)
|
||||
{
|
||||
// Array can have an inconsistent number of components. Cannot be represented by basic array.
|
||||
throw vtkm::cont::ErrorBadType("Cannot create a basic array from array with ValueType of " +
|
||||
vtkm::cont::TypeToString<T>());
|
||||
}
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic()
|
||||
using ComponentType = typename vtkm::VecTraits<T>::BaseComponentType;
|
||||
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleRuntimeVec<ComponentType>(numComponents));
|
||||
}
|
||||
template <typename T, typename S>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(void* mem)
|
||||
{
|
||||
return UnknownAHNewInstanceBasic<T>(typename vtkm::VecTraits<T>::IsSizeStatic{});
|
||||
return UnknownAHNewInstanceBasic<T, S>(mem, typename vtkm::VecTraits<T>::IsSizeStatic{});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTraitsTagSizeStatic)
|
||||
template <typename T, typename S>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(void*,
|
||||
vtkm::VecTraitsTagSizeStatic)
|
||||
{
|
||||
using FloatT = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::FloatDefault>;
|
||||
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<FloatT>{});
|
||||
}
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTraitsTagSizeVariable)
|
||||
template <typename T, typename S>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(void* mem,
|
||||
vtkm::VecTraitsTagSizeVariable)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Cannot create a basic array container from with ValueType of " +
|
||||
vtkm::IdComponent numComponents = UnknownAHNumberOfComponentsFlat<T, S>(mem);
|
||||
if (numComponents < 1)
|
||||
{
|
||||
// Array can have an inconsistent number of components. Cannot be represented by basic array.
|
||||
throw vtkm::cont::ErrorBadType("Cannot create a basic array from array with ValueType of " +
|
||||
vtkm::cont::TypeToString<T>());
|
||||
}
|
||||
template <typename T>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic()
|
||||
return UnknownAHContainer::Make(
|
||||
vtkm::cont::ArrayHandleRuntimeVec<vtkm::FloatDefault>(numComponents));
|
||||
}
|
||||
template <typename T, typename S>
|
||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(void* mem)
|
||||
{
|
||||
return UnknownAHNewInstanceFloatBasic<T>(typename vtkm::VecTraits<T>::IsSizeStatic{});
|
||||
return UnknownAHNewInstanceFloatBasic<T, S>(mem, typename vtkm::VecTraits<T>::IsSizeStatic{});
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
@ -352,8 +369,8 @@ inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S
|
||||
, DeleteFunction(detail::UnknownAHDelete<T, S>)
|
||||
, Buffers(detail::UnknownAHBuffers<T, S>)
|
||||
, NewInstance(detail::UnknownAHNewInstance<T, S>)
|
||||
, NewInstanceBasic(detail::UnknownAHNewInstanceBasic<T>)
|
||||
, NewInstanceFloatBasic(detail::UnknownAHNewInstanceFloatBasic<T>)
|
||||
, NewInstanceBasic(detail::UnknownAHNewInstanceBasic<T, S>)
|
||||
, NewInstanceFloatBasic(detail::UnknownAHNewInstanceFloatBasic<T, S>)
|
||||
, NumberOfValues(detail::UnknownAHNumberOfValues<T, S>)
|
||||
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T, S>)
|
||||
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T, S>)
|
||||
|
@ -254,6 +254,44 @@ void TryCopy()
|
||||
ARRAY_SIZE));
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "runtime vec size -> runtime vec size (different type)" << std::endl;
|
||||
using ComponentType = typename VTraits::BaseComponentType;
|
||||
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::UInt8>;
|
||||
vtkm::cont::ArrayHandle<SourceType> staticVecArray = MakeInputArray<SourceType>();
|
||||
vtkm::cont::ArrayHandleRuntimeVec<vtkm::UInt8> input =
|
||||
vtkm::cont::make_ArrayHandleRuntimeVec(staticVecArray);
|
||||
vtkm::cont::ArrayHandleRuntimeVec<ComponentType> output(input.GetNumberOfComponents());
|
||||
vtkm::cont::ArrayCopy(input, output);
|
||||
// Convert the arrays back to static vec sizes for comparison, because TestValues
|
||||
// uses a device array copy that may not work on runtime vec sizes.
|
||||
TestValues(staticVecArray,
|
||||
output.template AsArrayHandleBasic<vtkm::cont::ArrayHandle<ValueType>>());
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "basic -> recombined vec" << std::endl;
|
||||
using ComponentType = typename VTraits::BaseComponentType;
|
||||
vtkm::cont::ArrayHandle<ValueType> input = MakeInputArray<ValueType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
auto recombinedVec =
|
||||
vtkm::cont::UnknownArrayHandle{ output }.ExtractArrayFromComponents<ComponentType>();
|
||||
vtkm::cont::ArrayCopy(input, recombinedVec);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << "basic -> recombined vec (different type)" << std::endl;
|
||||
using SourceType = typename VTraits::template ReplaceComponentType<vtkm::Id>;
|
||||
using ComponentType = typename VTraits::BaseComponentType;
|
||||
vtkm::cont::ArrayHandle<SourceType> input = MakeInputArray<SourceType>();
|
||||
vtkm::cont::ArrayHandle<ValueType> output;
|
||||
auto recombinedVec =
|
||||
vtkm::cont::UnknownArrayHandle{ output }.ExtractArrayFromComponents<ComponentType>();
|
||||
vtkm::cont::ArrayCopy(input, recombinedVec);
|
||||
TestValues(input, output);
|
||||
}
|
||||
|
||||
// Test the copy methods in UnknownArrayHandle. Although this would be appropriate in
|
||||
// UnitTestUnknownArrayHandle, it is easier to test copies here.
|
||||
{
|
||||
|
@ -479,6 +479,18 @@ struct CheckExtractedArray
|
||||
auto extractedData = extractedPortal.Get(valueIndex);
|
||||
VTKM_TEST_ASSERT(test_equal(originalData, extractedData));
|
||||
}
|
||||
|
||||
// Make sure an extracted array stuffed back into an UnknownArrayHandle works.
|
||||
// This can happen when working with an extracted array that is passed to functions
|
||||
// that are implemented with UnknownArrayHandle.
|
||||
vtkm::cont::UnknownArrayHandle unknownArray{ extractedArray };
|
||||
|
||||
using ComponentType =
|
||||
typename vtkm::VecTraits<typename ExtractedArray::ValueType>::BaseComponentType;
|
||||
vtkm::cont::UnknownArrayHandle newBasic = unknownArray.NewInstanceBasic();
|
||||
newBasic.AsArrayHandle<vtkm::cont::ArrayHandleRuntimeVec<ComponentType>>();
|
||||
vtkm::cont::UnknownArrayHandle newFloat = unknownArray.NewInstanceFloatBasic();
|
||||
newFloat.AsArrayHandle<vtkm::cont::ArrayHandleRuntimeVec<vtkm::FloatDefault>>();
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user