mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 09:59:12 +00:00
Add 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.
This commit is contained in:
parent
3fe452662b
commit
c802adcbeb
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/filter/Filter.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayCopy.h>
|
||||||
|
|
||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
namespace filter
|
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>
|
template <typename Functor, typename... Args>
|
||||||
VTKM_CONT void CastAndCallScalarField(const vtkm::cont::UnknownArrayHandle& fieldArray,
|
VTKM_CONT void CastAndCallScalarField(const vtkm::cont::UnknownArrayHandle& fieldArray,
|
||||||
Functor&& functor,
|
Functor&& functor,
|
||||||
@ -178,6 +190,7 @@ protected:
|
|||||||
this->CastAndCallScalarField(
|
this->CastAndCallScalarField(
|
||||||
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
|
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
///@}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -189,6 +202,18 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
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>
|
template <vtkm::IdComponent VecSize, typename Functor, typename... Args>
|
||||||
VTKM_CONT void CastAndCallVecField(const vtkm::cont::UnknownArrayHandle& fieldArray,
|
VTKM_CONT void CastAndCallVecField(const vtkm::cont::UnknownArrayHandle& fieldArray,
|
||||||
Functor&& functor,
|
Functor&& functor,
|
||||||
@ -208,6 +233,52 @@ protected:
|
|||||||
this->CastAndCallVecField<VecSize>(
|
this->CastAndCallVecField<VecSize>(
|
||||||
field.GetData(), std::forward<Functor>(functor), std::forward<Args>(args)...);
|
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`
|
/// \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 vtkm::cont::DataSet DotProduct::DoExecute(const vtkm::cont::DataSet& inDataSet)
|
||||||
{
|
{
|
||||||
vtkm::cont::Field primaryField = this->GetFieldFromDataSet(0, inDataSet);
|
vtkm::cont::Field primaryField = this->GetFieldFromDataSet(0, inDataSet);
|
||||||
vtkm::cont::UnknownArrayHandle primaryArray = primaryField.GetData();
|
|
||||||
|
|
||||||
vtkm::cont::Field secondaryField = this->GetFieldFromDataSet(1, inDataSet);
|
vtkm::cont::Field secondaryField = this->GetFieldFromDataSet(1, inDataSet);
|
||||||
|
|
||||||
if (primaryArray.GetNumberOfComponentsFlat() !=
|
if (primaryField.GetData().GetNumberOfComponentsFlat() !=
|
||||||
secondaryField.GetData().GetNumberOfComponentsFlat())
|
secondaryField.GetData().GetNumberOfComponentsFlat())
|
||||||
{
|
{
|
||||||
throw vtkm::cont::ErrorFilterExecution(
|
throw vtkm::cont::ErrorFilterExecution(
|
||||||
@ -91,22 +89,10 @@ VTKM_CONT vtkm::cont::DataSet DotProduct::DoExecute(const vtkm::cont::DataSet& i
|
|||||||
|
|
||||||
vtkm::cont::UnknownArrayHandle outArray;
|
vtkm::cont::UnknownArrayHandle outArray;
|
||||||
|
|
||||||
if (primaryArray.IsBaseComponentType<vtkm::Float32>())
|
auto resolveArray = [&](const auto& concretePrimaryField) {
|
||||||
{
|
outArray = DoDotProduct(concretePrimaryField, secondaryField);
|
||||||
outArray =
|
};
|
||||||
DoDotProduct(primaryArray.ExtractArrayFromComponents<vtkm::Float32>(), secondaryField);
|
this->CastAndCallVariableVecField(primaryField, resolveArray);
|
||||||
}
|
|
||||||
else if (primaryArray.IsBaseComponentType<vtkm::Float64>())
|
|
||||||
{
|
|
||||||
outArray =
|
|
||||||
DoDotProduct(primaryArray.ExtractArrayFromComponents<vtkm::Float64>(), secondaryField);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
primaryArray = primaryField.GetDataAsDefaultFloat();
|
|
||||||
outArray =
|
|
||||||
DoDotProduct(primaryArray.ExtractArrayFromComponents<vtkm::FloatDefault>(), secondaryField);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->CreateResultField(inDataSet,
|
return this->CreateResultField(inDataSet,
|
||||||
this->GetOutputFieldName(),
|
this->GetOutputFieldName(),
|
||||||
|
Loading…
Reference in New Issue
Block a user