mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 01:49:02 +00:00
Merge topic 'cast-and-call-variable-vec'
c802adcbe Add support for CastAndCallVariableVecField in FilterField Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Li-Ta Lo <ollie@lanl.gov> Merge-request: !3064
This commit is contained in:
commit
00cd139be8
12
docs/changelog/cast-and-call-variable-vec.md
Normal file
12
docs/changelog/cast-and-call-variable-vec.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Added support for `CastAndCallVariableVecField` in `FilterField`
|
||||
|
||||
The `FilterField` class provides convenience functions for subclasses to
|
||||
determine the `ArrayHandle` type for scalar and vector fields. However, you
|
||||
needed to know the specific size of vectors. For filters that support an
|
||||
input field of any type, a new form, `CastAndCallVariableVecField` has been
|
||||
added. This calls the underlying functor with an `ArrayHandleRecombineVec`
|
||||
of the appropriate component type.
|
||||
|
||||
The `CastAndaCallVariableVecField` method also reduces the number of
|
||||
instances created by having a float fallback for any component type that
|
||||
does not satisfy the field types.
|
@ -13,6 +13,8 @@
|
||||
|
||||
#include <vtkm/filter/Filter.h>
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
@ -160,6 +162,16 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
///@{
|
||||
/// \brief Convenience method to get the array from a filter's input scalar field.
|
||||
///
|
||||
/// A field filter typically gets its input fields using the internal `GetFieldFromDataSet`.
|
||||
/// To use this field in a worklet, it eventually needs to be converted to an
|
||||
/// `ArrayHandle`. If the input field is limited to be a scalar field, then this method
|
||||
/// provides a convenient way to determine the correct array type. Like other `CastAndCall`
|
||||
/// methods, it takes as input a `Field` (or `UnknownArrayHandle`) and a function/functor
|
||||
/// to call with the appropriate `ArrayHandle` type.
|
||||
///
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCallScalarField(const vtkm::cont::UnknownArrayHandle& fieldArray,
|
||||
Functor&& functor,
|
||||
@ -178,6 +190,7 @@ protected:
|
||||
this->CastAndCallScalarField(
|
||||
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
|
||||
}
|
||||
///@}
|
||||
|
||||
|
||||
private:
|
||||
@ -189,6 +202,18 @@ private:
|
||||
};
|
||||
|
||||
protected:
|
||||
///@{
|
||||
/// \brief Convenience method to get the array from a filter's input vector field.
|
||||
///
|
||||
/// A field filter typically gets its input fields using the internal `GetFieldFromDataSet`.
|
||||
/// To use this field in a worklet, it eventually needs to be converted to an
|
||||
/// `ArrayHandle`. If the input field is limited to be a vector field with vectors of a
|
||||
/// specific size, then this method provides a convenient way to determine the correct array
|
||||
/// type. Like other `CastAndCall` methods, it takes as input a `Field` (or
|
||||
/// `UnknownArrayHandle`) and a function/functor to call with the appropriate `ArrayHandle`
|
||||
/// type. You also have to provide the vector size as the first template argument.
|
||||
/// For example `CastAndCallVecField<3>(field, functor);`.
|
||||
///
|
||||
template <vtkm::IdComponent VecSize, typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCallVecField(const vtkm::cont::UnknownArrayHandle& fieldArray,
|
||||
Functor&& functor,
|
||||
@ -208,6 +233,52 @@ protected:
|
||||
this->CastAndCallVecField<VecSize>(
|
||||
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
|
||||
}
|
||||
///@}
|
||||
|
||||
///@{
|
||||
/// This method is like `CastAndCallVecField` except that it can be used for a
|
||||
/// field of unknown vector size (or scalars). This method will call the given
|
||||
/// functor with an `ArrayHandleRecombineVec`.
|
||||
///
|
||||
/// Note that there are limitations with using `ArrayHandleRecombineVec` within a
|
||||
/// worklet. Because the size of the vectors are not known at compile time, you
|
||||
/// cannot just create an intermediate `Vec` of the correct size. Typically, you
|
||||
/// must allocate the output array (for example, with `ArrayHandleRuntimeVec`), and
|
||||
/// the worklet must iterate over the components and store them in the prealocated
|
||||
/// output.
|
||||
///
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCallVariableVecField(const vtkm::cont::UnknownArrayHandle& fieldArray,
|
||||
Functor&& functor,
|
||||
Args&&... args) const
|
||||
{
|
||||
if (fieldArray.IsBaseComponentType<vtkm::Float32>())
|
||||
{
|
||||
functor(fieldArray.ExtractArrayFromComponents<vtkm::Float32>(), std::forward<Args>(args)...);
|
||||
}
|
||||
else if (fieldArray.IsBaseComponentType<vtkm::Float64>())
|
||||
{
|
||||
functor(fieldArray.ExtractArrayFromComponents<vtkm::Float64>(), std::forward<Args>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Field component type is not directly supported. Copy to floating point array.
|
||||
vtkm::cont::UnknownArrayHandle floatArray = fieldArray.NewInstanceFloatBasic();
|
||||
vtkm::cont::ArrayCopy(fieldArray, floatArray);
|
||||
functor(floatArray.ExtractArrayFromComponents<vtkm::FloatDefault>(),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCallVariableVecField(const vtkm::cont::Field& field,
|
||||
Functor&& functor,
|
||||
Args&&... args) const
|
||||
{
|
||||
this->CastAndCallVariableVecField(
|
||||
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
|
||||
}
|
||||
///@}
|
||||
|
||||
/// \brief Create the output data set for `DoExecute`
|
||||
///
|
||||
|
@ -78,11 +78,9 @@ VTKM_CONT DotProduct::DotProduct()
|
||||
VTKM_CONT vtkm::cont::DataSet DotProduct::DoExecute(const vtkm::cont::DataSet& inDataSet)
|
||||
{
|
||||
vtkm::cont::Field primaryField = this->GetFieldFromDataSet(0, inDataSet);
|
||||
vtkm::cont::UnknownArrayHandle primaryArray = primaryField.GetData();
|
||||
|
||||
vtkm::cont::Field secondaryField = this->GetFieldFromDataSet(1, inDataSet);
|
||||
|
||||
if (primaryArray.GetNumberOfComponentsFlat() !=
|
||||
if (primaryField.GetData().GetNumberOfComponentsFlat() !=
|
||||
secondaryField.GetData().GetNumberOfComponentsFlat())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution(
|
||||
@ -91,22 +89,10 @@ VTKM_CONT vtkm::cont::DataSet DotProduct::DoExecute(const vtkm::cont::DataSet& i
|
||||
|
||||
vtkm::cont::UnknownArrayHandle outArray;
|
||||
|
||||
if (primaryArray.IsBaseComponentType<vtkm::Float32>())
|
||||
{
|
||||
outArray =
|
||||
DoDotProduct(primaryArray.ExtractArrayFromComponents<vtkm::Float32>(), secondaryField);
|
||||
}
|
||||
else if (primaryArray.IsBaseComponentType<vtkm::Float64>())
|
||||
{
|
||||
outArray =
|
||||
DoDotProduct(primaryArray.ExtractArrayFromComponents<vtkm::Float64>(), secondaryField);
|
||||
}
|
||||
else
|
||||
{
|
||||
primaryArray = primaryField.GetDataAsDefaultFloat();
|
||||
outArray =
|
||||
DoDotProduct(primaryArray.ExtractArrayFromComponents<vtkm::FloatDefault>(), secondaryField);
|
||||
}
|
||||
auto resolveArray = [&](const auto& concretePrimaryField) {
|
||||
outArray = DoDotProduct(concretePrimaryField, secondaryField);
|
||||
};
|
||||
this->CastAndCallVariableVecField(primaryField, resolveArray);
|
||||
|
||||
return this->CreateResultField(inDataSet,
|
||||
this->GetOutputFieldName(),
|
||||
|
Loading…
Reference in New Issue
Block a user