% -*- latex -*-

\chapter{Basic Array Handles}
\label{chap:BasicArrayHandles}

\index{array handle|(}

Chapter \ref{chap:DataSet} describes the basic data sets used by \VTKm.
This chapter dives deeper into how \VTKm represents data.
Ultimately, data structures like \vtkmcont{DataSet} can be broken down into arrays of numbers.
Arrays in \VTKm are managed by a unit called an \keyterm{array handle}.

An array handle, which is implemented with the \vtkmcont{ArrayHandle} class, manages an array of data that can be accessed or manipulated by \VTKm algorithms.
It is typical to construct an array handle in the control environment to pass data to an algorithm running in the execution environment.
It is also typical for an algorithm running in the execution environment to populate an array handle, which can then be read back in the control environment.
It is also possible for an array handle to manage data created by one \VTKm algorithm and passed to another, remaining in the execution environment the whole time and never copied to the control environment.

\begin{didyouknow}
  The array handle may have multiple of the array, one for the control environment and one for each device.
  However, depending on the device and how the array is being used, the array handle will only have one copy when possible.
  Copies between the environments are implicit and lazy.
  They are copied only when an operation needs data in an environment where the data are not.
\end{didyouknow}

\vtkmcont{ArrayHandle} behaves like a shared smart pointer in that when the C++ object is copied, each copy holds a reference to the same array.
These copies are reference counted so that when all copies of the \vtkmcont{ArrayHandle} are destroyed, any allocated memory is released.

An \textidentifier{ArrayHandle} defines the following methods.
Note, however, that the brief overview of this chapter will not cover the use of most of these methods.
Further descriptions are given in later chapters that explore even further the features of \textidentifier{ArrayHandle}s.

\begin{description}
\item[{\classmember*{ArrayHandle}{GetNumberOfValues}}]
  Returns the number of entries in the array.
\item[{\classmember*{ArrayHandle}{Allocate}}]
  Resizes the array to include the number of entries given.
  Any previously stored data might be discarded.
\item[{\classmember*{ArrayHandle}{ReleaseResourcesExecution}}]
  If the \textidentifier{ArrayHandle} is holding any data on a device (such as a GPU), that memory is released to be used elsewhere.
  No data is lost from this call.
  Any data on the released resources is copied to the control environment (the local CPU) before the memory is released.
\item[{\classmember*{ArrayHandle}{ReleaseResources}}]
  Releases all memory managed by this \textidentifier{ArrayHandle}.
  Any data in this memory is lost.
\item[{\classmember*{ArrayHandle}{SyncControlArray}}]
  Makes sure any data in the execution environment is also available in the control environment.
  This method is useful when timing parallel algorithms and you want to include the time to transfer data between parallel devices and their hosts.
\item[{\classmember*{ArrayHandle}{ReadPortal}}]
  Returns an array portal that can be used to access the data in the array handle in the control environment.
  The data in the array portal can only be read.
  Array portals are described in Section~\ref{sec:ArrayPortals}.
\item[{\classmember*{ArrayHandle}{WritePortal}}]
  Returns an array portal that can be used to access the data in the array handle in the control environment.
  The data in the array portal can be both read and written.
  Array portals are described in Section~\ref{sec:ArrayPortals}.
\item[{\classmember*{ArrayHandle}{PrepareForInput}}]
  Readies the data as input to a parallel algorithm.
  See Section~\ref{sec:ArrayHandle:InterfaceToExecutionEnvironment} for more details.
\item[{\classmember*{ArrayHandle}{PrepareForOutput}}]
  Readies the data as output to a parallel algorithm.
  See Section~\ref{sec:ArrayHandle:InterfaceToExecutionEnvironment} for more details.
\item[{\classmember*{ArrayHandle}{PrepareForInPlace}}]
  Readies the data as input and output to a parallel algorithm.
  See Section~\ref{sec:ArrayHandle:InterfaceToExecutionEnvironment} for more details.
\item[{\classmember*{ArrayHandle}{DeepCopyFrom}}]
  Given an \textidentifier{ArrayHandle} of the same type, deep copies the data from the provided array to this array.
  The array will be resized as necessary.
\item[{\classmember*{ArrayHandle}{IsOnHost}}]
  Returns true if the data are available on the host memory (that is, available in the control environment).
\item[{\classmember*{ArrayHandle}{IsOnDevice}}]
  Returns true if the data are available on the specific device.
\end{description}


\section{Creating Array Handles}
\label{sec:CreatingArrayHandles}

\vtkmcont{ArrayHandle} is templated on the type of values being stored in the array.
There are multiple ways to create and populate an array handle.
The default \vtkmcont{ArrayHandle} constructor will create an empty array with nothing allocated in either the control or execution environment.
This is convenient for creating arrays used as the output for algorithms.

\vtkmlisting{Creating an \textidentifier{ArrayHandle} for output data.}{CreateArrayHandle.cxx}

Chapter \ref{chap:AccessingAllocatingArrays} describes in detail how to allocate memory and access data in an \textidentifier{ArrayHandle}.
However, you can use the \vtkmcont{make\_ArrayHandle} function for a simplified way to create an \textidentifier{ArrayHandle} with data.

\textidentifier{make\_ArrayHandle} has many forms.
An easy form to use takes an initializer list and creates a basic \textidentifier{ArrayHandle} with it.
This allows you to create short \textidentifier{ArrayHandle}s from literals.

\vtkmlisting{Creating an \textidentifier{ArrayHandle} from initially specified values.}{ArrayHandleFromInitializerList.cxx}

One problem with creating an array from an initializer list like this is that it can be tricky to specify the exact value type of the \textidentifier{ArrayHandle}.
The value type of the \textidentifier{ArrayHandle} will be the same types as the literals in the initializer list, but that might not match the type you actually need.
This is particularly true for types like \vtkm{Id} and \vtkm{FloatDefault}, which can change depending on compile options.
To specify the exact value type to use, give that type as a template argument to the \vtkmcont{make\_ArrayHandle} function.

\vtkmlisting{Creating a typed \textidentifier{ArrayHandle} from initially specified values.}{ArrayHandleFromInitializerListTyped.cxx}

Constructing an \textidentifier{ArrayHandle} that points to a provided C array is also straightforward.
To do this, call \textidentifier{make\_ArrayHandle} with the array pointer, the number of values in the C array, and a \vtkm{CopyFlag}.
This last argument can be either \classmember{CopyFlag}{On} to copy the array or \classmember{CopyFlag}{Off} to share the provided buffer.

\vtkmlisting{Creating an \textidentifier{ArrayHandle} that points to a provided C array.}{ArrayHandleFromCArray.cxx}

\index{vector}\index{std::vector}%
Likewise, you can use \textidentifier{make\_ArrayHandle} to transfer data from a \textcode{std::vector} to an \textidentifier{ArrayHandle}.
This form of \textidentifier{make\_ArrayHandle} takes the \textcode{std::vector} as the first argument and a \vtkm{CopyFlag} as the second argument.

\vtkmlisting[ex:ArrayHandleFromVector]{Creating an \textidentifier{ArrayHandle} that points to a provided \textcode{std::vector}.}{ArrayHandleFromVector.cxx}

As hinted at earlier, it is possible to send \classmember{CopyFlag}{Off} to \textidentifier{make\_ArrayHandle} to wrap an \textidentifier{ArrayHandle} around an existing C array or \textcode{std::vector}.
Doing so allows you to send the data to the \textidentifier{ArrayHandle} without copying it.
It also provides a mechanism for \VTKm to write directly into your array.
However, \emph{be aware} that if you change or delete the data provided, the internal state of \textidentifier{ArrayHandle} becomes invalid and undefined behavior can ensue.
A common manifestation of this error happens when a \textcode{std::vector} goes out of scope.
This subtle interaction will cause the \vtkmcont{ArrayHandle} to point to an unallocated portion of the memory heap.
The following example provides an erroneous use of \textidentifier{ArrayHandle} and some ways to fix it.

\vtkmlisting[ex:ArrayOutOfScope]{Invalidating an \textidentifier{ArrayHandle} by letting the source \textcode{std::vector} leave scope.}{ArrayOutOfScope.cxx}

An easy way around the problem of having an \textidentifier{ArrayHandle}'s data going out of scope is to copy the data into the \textidentifier{ArrayHandle}.
Simply make the \vtkm{CopyFlag} argument be \classmember*{CopyFlag}{On} to copy the data.
This solution is shown on line \ref{ex:ArrayOutOfScope.cxx:CopyFlagOn} of Example \ref{ex:ArrayOutOfScope}.

What if you have a \textcode{std::vector} that you want to pass to an \textidentifier{ArrayHandle} and then want to only use in the \textidentifier{ArrayHandle}?
In this case, it is wasteful to have to copy the data, but you also do not want to be responsible for keeping the \textcode{std::vector} in scope.
To handle this, there is a special \vtkmcont{make\_ArrayHandleMove} that will move the memory out of the \textcode{std::vector} and into the \textidentifier{ArrayHandle}.
\textidentifier{make\_ArrayHandleMove} takes an ``rvalue'' version of a \textcode{std::vector}.
To create an ``rvalue'', use the \textcode{std::move} function provided by C++.
Once \textidentifier{make\_ArrayHandleMove} is called, the provided \textcode{std::vector} becomes invalid and any further access to it is undefined.
This solution is shown on line \ref{ex:ArrayOutOfScope.cxx:MoveVector} of Example \ref{ex:ArrayOutOfScope}.


\section{Deep Array Copies}
\label{sec:DeepArrayCopies}

\index{deep array copy|(}
\index{array handle!deep copy|(}

As stated previously, an \textidentifier{ArrayHandle} object behaves as a smart pointer that copies references to the data without copying the data itself.
This is clearly faster and more memory efficient than making copies of the data itself and usually the behavior desired.
However, it is sometimes the case that you need to make a separate copy of the data.

The easiest way to copy \textidentifier{ArrayHandle}s is to use the \classmember{ArrayHandle}{DeepCopyFrom} method.

\vtkmlisting{Deep copy \textidentifier{ArrayHandle}s of the same type.}{ArrayHandleDeepCopy.cxx}

However, the \classmember*{ArrayHandle}{DeepCopyFrom} method only works if the two \textidentifier{ArrayHandle}s are the exact same type.
To simplify copying the data between \textidentifier{ArrayHandle}s of different types, \VTKm comes with the \vtkmcont{ArrayCopy} convenience function defined in \vtkmheader{vtkm/cont}{ArrayCopy.h}.
\textidentifier{ArrayCopy} takes the array to copy from (the source) as its first argument and the array to copy to (the destination) as its second argument.
The destination array will be properly reallocated to the correct size.

\vtkmlisting[ex:ArrayCopy]{Using \textidentifier{ArrayCopy}.}{ArrayCopy.cxx}

\index{array handle!deep copy|)}
\index{deep array copy|)}


\section{The Hidden Second Template Parameter}

\index{array handle!storage|(}
\index{storage|(}

We have already seen that \vtkmcont{ArrayHandle} is a templated class with the template parameter indicating the type of values stored in the array.
However, \textidentifier{ArrayHandle} has a second hidden parameter that indicates the \keyterm{storage} of the array.
We have so far been able to ignore this second template parameter because \VTKm will assign a default storage for us that will store the data in a basic array.

\begin{vtkmexample}{Declaration of the \protect\vtkmcont{ArrayHandle} templated class.}
template<typename T, typename StorageTag = VTKM_DEFAULT_STORAGE_TAG>
class ArrayHandle;
\end{vtkmexample}

Changing the storage of an \textidentifier{ArrayHandle} lets us do many weird and wonderful things.
We will explore these options in later chapters, but for now we can ignore this second storage template parameter.
However, there are a couple of things to note concerning the storage.

First, if the compiler gives an error concerning your use of \textidentifier{ArrayHandle}, the compiler will report the \textidentifier{ArrayHandle} type with not one but two template parameters.
A second template parameter of \vtkmcont{StorageTagBasic} can be ignored.

Second, if you write a function, method, or class that is templated based on an \textidentifier{ArrayHandle} type, it is good practice to accept \textidentifier{ArrayHandle}s with non-default storage types.
There are two ways to do this.
The first way is to template both the value type and the storage type.

\vtkmlisting{Templating a function on an \textidentifier{ArrayHandle}'s parameters}{ArrayHandleParameterTemplate.cxx}

The second way is to template the whole array type rather than the sub types.
If you create a template where you expect one of the parameters to be an \textidentifier{ArrayHandle}, you should use the \vtkmmacro{VTKM\_IS\_ARRAY\_HANDLE} macro to verify that the type is indeed an \textidentifier{ArrayHandle}.

\vtkmlisting{A template parameter that should be an \textidentifier{ArrayHandle}.}{ArrayHandleFullTemplate.cxx}

\index{storage|)}
\index{array handle!storage|)}

\section{Mutability}

\index{array handle!const|(}

One subtle feature of \textidentifier{ArrayHandle} is that the class is, in principle, a pointer to an array pointer.
This means that the data in an \textidentifier{ArrayHandle} is always mutable even if the class is declared \textcode{const}.
You can change the contents of ``constant'' arrays via methods like \classmember*{ArrayHandle}{WritePortal} and \classmember*{ArrayHandle}{PrepareForOutput}.
It is even possible to change the underlying array allocation with methods like \classmember*{ArrayHandle}{Allocate} and \classmember*{ArrayHandle}{ReleaseResources}.
The upshot is that you can (sometimes) pass output arrays as constant \textidentifier{ArrayHandle} references.

So if a constant \textidentifier{ArrayHandle} can have its contents modified, what is the difference between a constant reference and a non-constant reference?
The difference is that the constant reference can change the array's content, but not the array itself.
Basically, this means that you cannot perform shallow copies into constant \textidentifier{ArrayHandle}s.
This can be a pretty big limitation, and many of \VTKm's internal device algorithms still require non-constant references for outputs.

\index{array handle!const|)}

\index{array handle|)}
