VTK  9.3.20240423
Public Types | List of all members
vtkArrayDispatch Class Reference

vtkDataArray code generator/dispatcher. More...

#include <vtkArrayDispatch.h>

Public Types

typedef vtkTypeList::Create< double, float > Reals
 A TypeList containing all real ValueTypes.
 
typedef vtkTypeList::Unique< vtkTypeList::Create< char, int, long, longlong, short, signedchar, unsignedchar, unsignedint, unsignedlong, unsignedlonglong, unsignedshort, vtkIdType > >::Result Integrals
 A Typelist containing all integral ValueTypes.
 
typedef vtkTypeList::Append< Reals, Integrals >::Result AllTypes
 A Typelist containing all standard VTK array ValueTypes.
 

Detailed Description

vtkDataArray code generator/dispatcher.

vtkArrayDispatch implements a mechanism for generating optimized code for multiple subclasses of vtkDataArray at once. Using a TypeList based approach (see vtkTypeList), a templated worker implementation is generated for a restricted or unrestricted set of vtkDataArray subclasses.

A more detailed description of this class and related tools can be found here.

The primary goals of this class are to simplify multi-array dispatch implementations, and provide tools to lower compilation time and binary size (i.e. avoiding 'template explosions').

vtkArrayDispatch is also intended to replace code that currently relies on the encapsulation-breaking vtkDataArray::GetVoidPointer method. Not all subclasses of vtkDataArray use the memory layout assumed by GetVoidPointer; calling this method on, e.g. a vtkSOADataArrayTemplate will trigger a deep copy of the array data into an AOS buffer. This is very inefficient and should be avoided.

The vtkDataArrayRange.h utilities are worth mentioning here, as they allow vtkArrayDispatch workers to operate on selected concrete subclasses for 'fast paths', yet fallback to using the slower vtkDataArray API for uncommon array types. This helps mitigate the "template explosion" issues that can result from instantiating a large worker functions for many array types.

These dispatchers extend the basic functionality of vtkTemplateMacro with the following features:

The basic Dispatch implementation will generate code paths for all arrays in the application-wide array list, and operates on a single array.

Dispatchers that start with Dispatch2 operate on 2 arrays simultaneously, while those that begin with Dispatch3 operate on 3 arrays.

To reduce compile time and binary size, the following dispatchers can be used to restrict the set of arrays that will be used. There are versions of these that operate on 1, 2, or 3 arrays:

Execution: There are three components to a dispatch: The dispatcher, the worker, and the array(s). They are combined like so:

bool result = Dispatcher<...>::Execute(array, worker);

For convenience, the dispatcher may be aliased to a shorter name, e.g.:

using MyDispatcher = vtkArrayDispatch::SomeDispatcher<...>;
MyWorker worker;
bool result = MyDispatcher::Execute(array, worker);

Return value: The Execute method of the dispatcher will return true if a code path matching the array arguments is found, or false if the arrays are not supported. If false is returned, the arrays will not be modified, and the worker will not be executed.

Workers: The dispatch requires a Worker functor that performs the work. For single array, the functor must be callable where the first parameter is an array object. For 2-array dispatch, the first two arguments must be (array1, array2). For 3-array dispatch, the first three arguments must be (array1, array2, array3). Workers are passed by reference, so stateful functors are permitted if additional input/output data is needed and not being passed as additional parameters to the Execute method.

A simple worker implementation for triple dispatch:

struct MyWorker
{
template <typename Array1T, typename Array2T, typename Array3T>
void operator()(Array1T *array1, Array2T *array2, Array3T *array3)
{
// Do work using vtkGenericDataArray API...
}
};

Note that optimized implementations (e.g. for AoS arrays vs SoA arrays) can be supported by providing overloads of operator() that have more restrictive template parameters.

A worker's operator() implementation can accept additional parameters that follow the arrays. These parameters are passed to the dispatcher during execution. For instance, this worker scales an array by a runtime-value, writing it into a second array:

struct ScaleArray
{
template <typename ArraySrc, typename ArrayDst>
void operator()(ArraySrc *srcArray, ArrayDst *dstArray,
double scaleFactor) const
{
using SrcType = vtk::GetAPIType<ArraySrc>;
using DstType = vtk::GetAPIType<ArrayDst>;
const auto srcRange = vtk::DataArrayValueRange(srcArray);
auto dstRange = vtk::DataArrayValueRange(dstArray);
assert(srcRange.size() == dstRange.size());
auto dstIter = dstRange.begin();
for (SrcType srcVal : srcRange)
{
*dstIter++ = static_cast<DstType>(srcVal * scaleFactor);
}
}
};
vtkDataArray *src = ...;
vtkDataArray *dst = ...;
// Scale src by 3 (scaleFactor) and store in dst:
if (!vtkArrayDispatch::Dispatch2::Execute(src, dst, ScaleArray, 3))
{
scaleArray(src, dst, 3);
}
abstract superclass for arrays of numeric data
typename detail::GetAPITypeImpl< ArrayType, ForceValueTypeForVtkDataArray >::APIType GetAPIType
VTK_ITER_INLINE auto DataArrayValueRange(const ArrayTypePtr &array, ValueIdType start=-1, ValueIdType end=-1) -> typename detail::SelectValueRange< ArrayTypePtr, TupleSize, ForceValueTypeForVtkDataArray >::type
Generate an stl and for-range compatible range of flat AOS iterators from a vtkDataArray.

Examples: See TestArrayDispatchers.cxx for examples of each dispatch type and ExampleDataArrayRangeDispatch.cxx for more real-world examples.

See also
vtkDataArrayAccessor
Online Examples:

Tests:
vtkArrayDispatch (Tests)

Member Typedef Documentation

◆ Reals

typedef vtkTypeList::Create<double, float> vtkArrayDispatch::Reals

A TypeList containing all real ValueTypes.

Definition at line 219 of file vtkArrayDispatch.h.

◆ Integrals

typedef vtkTypeList::Unique<vtkTypeList::Create<char,int,long,longlong,short,signedchar,unsignedchar,unsignedint,unsignedlong,unsignedlonglong,unsignedshort,vtkIdType>>::Result vtkArrayDispatch::Integrals

A Typelist containing all integral ValueTypes.

Definition at line 226 of file vtkArrayDispatch.h.

◆ AllTypes

typedef vtkTypeList::Append<Reals,Integrals>::Result vtkArrayDispatch::AllTypes

A Typelist containing all standard VTK array ValueTypes.

Definition at line 231 of file vtkArrayDispatch.h.


The documentation for this class was generated from the following file: