DeprecatedZeroCopyArray.tex 5.84 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
\subsection{Reusing Simulation Memory for Non-VTK Compliant Memory Layouts}\label{appendix:alternatememorylayout}
Recent work in VTK has added the ability to reuse the simulation's memory and data structures
in the co-processing pipeline.
We start with information on creating a class that derives from vtkDataArray that uses pre-allocated memory
that does not match up with VTK's expected layout. The abstract class to derive from for this
purpose is the vtkMappedDataArray. We first go through an example of this with the vtkCPExodusIIResultsArrayTemplate class
which is part of VTK.
The vtkCPExodusIIResultsArrayTemplate class is a
templated class that is a concrete implementation of vtkMappedDataArray. This class
should only be used if the data array has more than one component.
It can be used
as is if the simulation memory layout has the following constraints:
\begin{itemize}
\item The components of the data are each stored in contiguous arrays.
\item The component array data is stored in the same order as the points or cells in
the VTK dataset for point data or cell data, respectively.
\end{itemize}
If these two conditions are met then the main function of interest in this class
is:
\begin{itemize}
\item void SetExodusScalarArrays(std::vector\textless Scalar*\textgreater arrays, vtkIdType numTuples, bool save)
\end{itemize}
Here, arrays is used to pass the pointers to the beginning of each component array. The size of arrays
sets the number of components in the vtkCPExodusIIResultsArrayTemplate object. The number of tuples
is set by numTuples. Finally, if save is set to false then the object will delete the arrays
using the delete method on each component array when it is done with the memory. Otherwise it
assumes that the memory will be de-allocated elsewhere. The following code snippet demonstrates
its use.
\begin{minted}{c++}
vtkCPExodusIIResultsArrayTemplate<double>* vtkarray =
  vtkCPExodusIIResultsArrayTemplate<double>::New();
vtkarray->SetName("velocity");
std::vector<double*> simulationarrays;
simulationarrays.push_back(xvelocity);
simulationarrays.push_back(yvelocity);
simulationarrays.push_back(zvelocity);
vtkarray->SetExodusScalarArrays(myarrays, grid->GetNumberOfPoints(), true);
grid->GetPointData()->AddArray(vtkarray);
vtkarray->Delete();
\end{minted}

If the vtkCPExodusIIResultsArrayTemplate class is not appropriate for mapping
simulation memory to VTK memory, a class that derives from vtkMappedDataArray
will need to be written. The virtual methods that need to be reimplemented are (note that
Scalar is the templated data type):
\begin{itemize}
\item void Initialize()
\item void GetTuples(vtkIdList *ptIds, vtkAbstractArray *output)
\item void GetTuples(vtkIdType p1, vtkIdType p2, vtkAbstractArray *output)
\item void Squeeze()
\item vtkArrayIterator *NewIterator()
\item vtkIdType LookupValue(vtkVariant value)
\item void LookupValue(vtkVariant value, vtkIdList *ids)
\item vtkVariant GetVariantValue(vtkIdType idx)
\item void ClearLookup()
\item double* GetTuple(vtkIdType i)
\item void GetTuple(vtkIdType i, double *tuple)
\item vtkIdType LookupTypedValue(Scalar value)
\item void LookupTypedValue(Scalar value, vtkIdList *ids)
\item Scalar GetValue(vtkIdType idx)
\item Scalar\& GetValueReference(vtkIdType idx)
\item void GetTupleValue(vtkIdType idx, Scalar *t)
\end{itemize}

Since once the object is properly set up it should be considered a read-only class (i.e.
nothing in VTK should be modifying any of its contents), the following methods
should be implemented with only errors to ensure they aren't being used:
\begin{itemize}
\item int Allocate(vtkIdType sz, vtkIdType ext)
\item int Resize(vtkIdType numTuples)
\item void SetNumberOfTuples(vtkIdType number)
\item void SetTuple(vtkIdType i, vtkIdType j, vtkAbstractArray *source)
\item void SetTuple(vtkIdType i, const float *source)
\item void SetTuple(vtkIdType i, const double *source)
\item void InsertTuple(vtkIdType i, vtkIdType j, vtkAbstractArray *source)
\item void InsertTuple(vtkIdType i, const float *source)
\item void InsertTuple(vtkIdType i, const double *source)
\item void InsertTuples(vtkIdList *dstIds, vtkIdList *srcIds, vtkAbstractArray *source)
\item vtkIdType InsertNextTuple(vtkIdType j, vtkAbstractArray *source)
\item vtkIdType InsertNextTuple(const float *source)
\item vtkIdType InsertNextTuple(const double *source)
\item void DeepCopy(vtkAbstractArray *aa)
\item void DeepCopy(vtkDataArray *da)
\item void InterpolateTuple(vtkIdType i, vtkIdList *ptIndices, vtkAbstractArray* source,  double* weights)
\item void InterpolateTuple(vtkIdType i, vtkIdType id1, vtkAbstractArray *source1, vtkIdType id2, vtkAbstractArray *source2, double t)
\item void SetVariantValue(vtkIdType idx, vtkVariant value)
\item void RemoveTuple(vtkIdType id)
\item void RemoveFirstTuple()
\item void RemoveLastTuple()
\item void SetTupleValue(vtkIdType i, const Scalar *t)
\item void InsertTupleValue(vtkIdType i, const Scalar *t)
\item vtkIdType InsertNextTupleValue(const Scalar *t)
\item void SetValue(vtkIdType idx, Scalar value)
\item vtkIdType InsertNextValue(Scalar v)
\item void InsertValue(vtkIdType idx, Scalar v)
\end{itemize}

Using classes derived from vtkMappedDataArray along with any of the topologically
structured grids, the adaptor will use a negligible amount of additional memory in creating VTK data structures
representing simulation grids and fields. For vtkPolyDatas and vtkUnstructuredGrids,
the memory to store the cells can still be substantial. VTK has recently added
the vtkMappedUnstructuredGrid class as a way to do this. Since vtkUnstructuredGrids can
store all of the cells that a vtkPolyData can, we have not done the same for vtkPolyDatas though.
Using the vtkMappedUnstructuredGrid class to represent the simulation code's grid
inside of VTK is quite complex and beyond the scope of this document. For developer's interested
in using this though we refer them to \url{www.vtk.org/Wiki/VTK/InSituDataStructures}.