mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +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)
|
if (this->Container)
|
||||||
{
|
{
|
||||||
newArray.Container = this->Container->NewInstanceBasic();
|
newArray.Container = this->Container->NewInstanceBasic(this->Container->ArrayHandlePointer);
|
||||||
}
|
}
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
@ -237,7 +237,8 @@ VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstanceFloatBasic() const
|
|||||||
UnknownArrayHandle newArray;
|
UnknownArrayHandle newArray;
|
||||||
if (this->Container)
|
if (this->Container)
|
||||||
{
|
{
|
||||||
newArray.Container = this->Container->NewInstanceFloatBasic();
|
newArray.Container =
|
||||||
|
this->Container->NewInstanceFloatBasic(this->Container->ArrayHandlePointer);
|
||||||
}
|
}
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ struct VTKM_CONT_EXPORT UnknownAHContainer
|
|||||||
using NewInstanceType = void*();
|
using NewInstanceType = void*();
|
||||||
NewInstanceType* NewInstance;
|
NewInstanceType* NewInstance;
|
||||||
|
|
||||||
using NewInstanceBasicType = std::shared_ptr<UnknownAHContainer>();
|
using NewInstanceBasicType = std::shared_ptr<UnknownAHContainer>(void*);
|
||||||
NewInstanceBasicType* NewInstanceBasic;
|
NewInstanceBasicType* NewInstanceBasic;
|
||||||
NewInstanceBasicType* NewInstanceFloatBasic;
|
NewInstanceBasicType* NewInstanceFloatBasic;
|
||||||
|
|
||||||
@ -307,39 +307,56 @@ private:
|
|||||||
explicit UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S>& array);
|
explicit UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S>& array);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename S>
|
||||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeStatic)
|
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(void*, vtkm::VecTraitsTagSizeStatic)
|
||||||
{
|
{
|
||||||
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<T>{});
|
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<T>{});
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T, typename S>
|
||||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeVariable)
|
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>());
|
vtkm::cont::TypeToString<T>());
|
||||||
|
}
|
||||||
|
using ComponentType = typename vtkm::VecTraits<T>::BaseComponentType;
|
||||||
|
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleRuntimeVec<ComponentType>(numComponents));
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T, typename S>
|
||||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic()
|
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>
|
template <typename T, typename S>
|
||||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTraitsTagSizeStatic)
|
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(void*,
|
||||||
|
vtkm::VecTraitsTagSizeStatic)
|
||||||
{
|
{
|
||||||
using FloatT = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::FloatDefault>;
|
using FloatT = typename vtkm::VecTraits<T>::template ReplaceBaseComponentType<vtkm::FloatDefault>;
|
||||||
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<FloatT>{});
|
return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<FloatT>{});
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T, typename S>
|
||||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTraitsTagSizeVariable)
|
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>());
|
vtkm::cont::TypeToString<T>());
|
||||||
|
}
|
||||||
|
return UnknownAHContainer::Make(
|
||||||
|
vtkm::cont::ArrayHandleRuntimeVec<vtkm::FloatDefault>(numComponents));
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T, typename S>
|
||||||
std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic()
|
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>
|
template <typename T, typename S>
|
||||||
@ -352,8 +369,8 @@ inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S
|
|||||||
, DeleteFunction(detail::UnknownAHDelete<T, S>)
|
, DeleteFunction(detail::UnknownAHDelete<T, S>)
|
||||||
, Buffers(detail::UnknownAHBuffers<T, S>)
|
, Buffers(detail::UnknownAHBuffers<T, S>)
|
||||||
, NewInstance(detail::UnknownAHNewInstance<T, S>)
|
, NewInstance(detail::UnknownAHNewInstance<T, S>)
|
||||||
, NewInstanceBasic(detail::UnknownAHNewInstanceBasic<T>)
|
, NewInstanceBasic(detail::UnknownAHNewInstanceBasic<T, S>)
|
||||||
, NewInstanceFloatBasic(detail::UnknownAHNewInstanceFloatBasic<T>)
|
, NewInstanceFloatBasic(detail::UnknownAHNewInstanceFloatBasic<T, S>)
|
||||||
, NumberOfValues(detail::UnknownAHNumberOfValues<T, S>)
|
, NumberOfValues(detail::UnknownAHNumberOfValues<T, S>)
|
||||||
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T, S>)
|
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T, S>)
|
||||||
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T, S>)
|
, NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T, S>)
|
||||||
|
@ -254,6 +254,44 @@ void TryCopy()
|
|||||||
ARRAY_SIZE));
|
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
|
// Test the copy methods in UnknownArrayHandle. Although this would be appropriate in
|
||||||
// UnitTestUnknownArrayHandle, it is easier to test copies here.
|
// UnitTestUnknownArrayHandle, it is easier to test copies here.
|
||||||
{
|
{
|
||||||
|
@ -479,6 +479,18 @@ struct CheckExtractedArray
|
|||||||
auto extractedData = extractedPortal.Get(valueIndex);
|
auto extractedData = extractedPortal.Get(valueIndex);
|
||||||
VTKM_TEST_ASSERT(test_equal(originalData, extractedData));
|
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