% -*- latex -*-

\chapter{Accessing and Allocating Array Handles}
\label{chap:AccessingAllocatingArrays}

\index{array handle|(}

So far we have seen examples of creating \vtkmcont{ArrayHandle}s from normal C++ arrays (Chapter \ref{chap:BasicArrayHandles}) and creating some special arrays (Chapter \ref{chap:FancyArrayHandles}).
However, we have so far avoided discussing how to access the actual data in \textidentifier{ArrayHandle}s.
So far we have only accessed \textidentifier{ArrayHandle} data indirectly through other \VTKm features such as worklets.

In this chapter we describe how to more directly access the data in an \textidentifier{ArrayHandle}, how to allocate space for data in an \textidentifier{ArrayHandle}, and how data is transferred to the execution environment to be used in a worklet.


\section{Array Portals}
\label{sec:ArrayPortals}

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

An array handle defines auxiliary structures called \keyterm{array portals}
that provide direct access into its data. An array portal is a simple
object that is somewhat functionally equivalent to an STL-type iterator, but
with a much simpler interface. Array portals can be read-only (const) or
read-write and they can be accessible from either the control environment
or the execution environment. All these variants have similar interfaces
although some features that are not applicable can be left out.

An array portal object contains each of the following:
\begin{description}
\item[\classmember*{ArrayPortal}{ValueType}]
  The type for each item in the array.
\item[\classmember*{ArrayPortal}{GetNumberOfValues}]
  A method that returns the number of entries in the array.
\item[\classmember*{ArrayPortal}{Get}]
  A method that returns the value at a given index.
\item[\classmember*{ArrayPortal}{Set}]
  A method that changes the value at a given index.
  This method does not need to exist for read-only (const) array portals.
\end{description}

The following code example defines an array portal for a simple C array of
scalar values. This definition has no practical value (it is covered by the
more general \vtkmcontinternal{ArrayPortalFromIterators}), but demonstrates
the function of each component.

\vtkmlisting{A simple array portal implementation.}{SimpleArrayPortal.cxx}

Although array portals are simple to implement and use, and array portals'
functionality is similar to iterators, there exists a great deal of code
already based on STL iterators and it is often convenient to interface
with an array through an iterator rather than an array portal. The
\vtkmcont{ArrayPortalToIterators} class can be used to convert an array
portal to an STL-compatible iterator. The class is templated on the array
portal type and has a constructor that accepts an instance of the array
portal. It contains the following features.
\begin{description}
\item[{\classmember*{ArrayPortalToIterators}{IteratorType}}]
  The type of an STL-compatible random-access iterator that can provide the same access as the array portal.
\item[{\classmember*{ArrayPortalToIterators}{GetBegin}}]
  A method that returns an STL-compatible iterator of type \classmember*{ArrayPortalToIterators}{IteratorType} that points to the beginning of the array.
\item[{\classmember*{ArrayPortalToIterators}{GetEnd}}]
  A method that returns an STL-compatible iterator of type \classmember*{ArrayPortalToIterators}{IteratorType} that points to the end of the array.
\end{description}

\vtkmlisting{Using \textidentifier{ArrayPortalToIterators}.}{ArrayPortalToIterators.cxx}

As a convenience, \vtkmheader{vtkm/cont}{ArrayPortalToIterators.h} also
defines a pair of functions named \vtkmcont*{ArrayPortalToIteratorBegin}
and \vtkmcont*{ArrayPortalToIteratorEnd}
that each take an array portal as an
argument and return a begin and end iterator, respectively.

\vtkmlisting{Using \textidentifier{ArrayPortalToIteratorBegin} and \textidentifier{ArrayPortalToIteratorEnd}.}{ArrayPortalToIteratorBeginEnd.cxx}

\textidentifier{ArrayHandle} contains two internal type definitions for array
portal types that are capable of interfacing with the underlying data in
the control environment. These are \classmember*{ArrayHandle}{WritePortalType}
and \classmember*{ArrayHandle}{ReadPortalType},
which define read-write and read-only
array portals, respectively.

\textidentifier{ArrayHandle} also contains similar type definitions for
array portals in the execution environment. Because these types are
dependent on the device adapter used for execution, these type definitions are
embedded in a templated class named \classmember*{ArrayHandle}{ExecutionTypes}.
Within \classmember*{ArrayHandle}{ExecutionTypes} are the type definitions
\textcode{Portal} and \textcode{PortalConst} defining the read-write and
read-only (const) array portals, respectively, for the execution
environment for the given device adapter tag.

Because \vtkmcont{ArrayHandle} is control environment object, it provides the methods \classmember*{ArrayHandle}{ReadPortal} and \classmember*{ArrayHandle}{WritePortal} to get the associated array portal objects.
These methods also have the side effect of refreshing the control environment copy of the data as if you called \classmember*{ArrayHandle}{SyncControlArray}.
%Be aware that when an \textidentifier{ArrayHandle} is created with a pointer or \textcode{std::vector}, it is put in a read-only mode, and \classmember*{ArrayHandle}{WritePortal} can fail (although \classmember*{ArrayHandle}{ReadPortal} will still work).
Be aware that calling \classmember*{ArrayHandle}{WritePortal} will invalidate any copy in the execution environment, meaning that any subsequent use will cause the data to be copied back again.

\vtkmlisting{Using portals from an \textidentifier{ArrayHandle}.}{ControlPortals.cxx}

\begin{didyouknow}
  Most operations on arrays in VTK-m should really be done in the execution
  environment. Keep in mind that whenever doing an operation using a
  control array portal, that operation will likely be slow for large
  arrays. However, some operations, like performing file I/O, make sense in
  the control environment.
\end{didyouknow}

\begin{commonerrors}
  To ensure that access to \textidentifier{ArrayHandle}s are thread safe, the portals returned from \classmember*{ArrayHandle}{ReadPortal} and \classmember*{ArrayHandle}{WritePortal} will ``lock'' the \textidentifier{ArrayHandle} they come from.
  A \classmember*{ArrayHandle}{ReadPortal} will prevent any writing to the \textidentifier{ArrayHandle} and a \classmember*{ArrayHandle}{WritePortal} will prevent any reads or writes.
  Thus, it is easy to deadlock a thread by getting a \classmember*{ArrayHandle}{ReadPortal} or \classmember*{ArrayHandle}{WritePortal} and then further attempt to access the \textidentifier{ArrayHandle}.
  Once the array portal is destroyed, the \textidentifier{ArrayHandle} will automatically be released for further reads and writes.
  Thus, code that uses a \classmember*{ArrayHandle}{ReadPortal} or \classmember*{ArrayHandle}{WritePortal} should be scoped to exist only as long as it is needed.
  Alternately, the returned array portals have a special \classmember*{ArrayPortal}{Detach} method that will release any locks on the \textidentifier{ArrayHandle} and will invalidate the array portal.
\end{commonerrors}

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


\section{Allocating and Populating Array Handles}
\label{sec:ArrayHandle:Allocate}
\label{sec:ArrayHandle:Populate}

\index{array handle!allocate}
\index{Allocate}

\vtkmcont{ArrayHandle} is capable of allocating its own memory. The most
straightforward way to allocate memory is to call the \classmember{ArrayHandle}{Allocate}
method. The \classmember*{ArrayHandle}{Allocate} method takes a single argument, which is
the number of elements to make the array.

\vtkmlisting{Allocating an \textidentifier{ArrayHandle}.}{ArrayHandleAllocate.cxx}

\begin{commonerrors}
  The ability to allocate memory is a key difference between
  \textidentifier{ArrayHandle} and many other common forms of smart
  pointers. When one \textidentifier{ArrayHandle} allocates new memory, all
  other \textidentifier{ArrayHandle}s pointing to the same managed memory
  get the newly allocated memory. This can be particularly surprising when
  the originally managed memory is empty. For example, older versions of
  \textcode{std::vector} initialized all its values by setting them to the
  same object. When a \textcode{vector} of \textidentifier{ArrayHandle}s
  was created and one entry was allocated, all entries changed to the same
  allocation.
\end{commonerrors}

\index{array handle!populate}

Once an \textidentifier{ArrayHandle} is allocated, it can be populated by using the portal returned from \classmember{ArrayHandle}{WritePortal}, as described in Section~\ref{sec:ArrayPortals}.
This is roughly the method used by the readers in the I/O package (Chapter~\ref{chap:FileIO}).

\vtkmlisting{Populating a newly allocated \textidentifier{ArrayHandle}.}{ArrayHandlePopulate.cxx}



\section{Compute Array Range}
\label{sec:ComputeArrayRange}

\index{range!array|(}
\index{array handle!range|(}
\index{array handle!minimum|(}
\index{array handle!maximum|(}

It is common to need to know the minimum and/or maximum values in an array.
To help find these values, \VTKm provides the \vtkmcont{ArrayRangeCompute} convenience function defined in \vtkmheader{vtkm/cont}{ArrayRangeCompute.h}.
\textidentifier{ArrayRangeCompute} simply takes an \textidentifier{ArrayHandle} on which to find the range of values.

If given an array with \vtkm{Vec} values, \textidentifier{ArrayRangeCompute} computes the range separately for each component of the \textidentifier{Vec}.
The return value for \textidentifier{ArrayRangeCompute} is \vtkmcont{ArrayHandle}\tparams{\vtkm{Range}}.
This returned array will have one value for each component of the input array's type.
So for example if you call \textidentifier{ArrayRangeCompute} on a \vtkmcont{ArrayHandle}\tparams{\vtkm{Id3}}, the returned array of \textidentifier{Range}s will have 3 values in it.
Of course, when \textidentifier{ArrayRangeCompute} is run on an array of scalar types, you get an array with a single value in it.

Each value of \vtkm{Range} holds the minimum and maximum value for that component.
The \textidentifier{Range} object is documented in Section~\ref{sec:Range}.

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

\begin{didyouknow}
  \textidentifier{ArrayRangeCompute} will compute the minimum and maximum values in parallel.
  If desired, you can specify the parallel hardware device used for the computation as an optional second argument to \textidentifier{ArrayRangeCompute}.
  You can specify the device using a runtime device tracker, which is documented in Section~\ref{sec:RuntimeDeviceTracker}.
\end{didyouknow}

\index{array handle!maximum|)}
\index{array handle!minimum|)}
\index{array handle!range|)}
\index{range!array|)}


\section{Interface to Execution Environment}
\label{sec:ArrayHandle:InterfaceToExecutionEnvironment}

\index{array handle!execution environment|(}

One of the main functions of the array handle is to allow an array to be defined in the control environment and then be used in the execution environment.
When using an \textidentifier{ArrayHandle} with filters, worklets, or algorithms, this transition is handled automatically.
However, it is also possible to invoke the transfer for a known device.
This is most useful when creating execution objects, as discussed in Chapter \ref{chap:ExecutionObjects}.

The \textidentifier{ArrayHandle} class manages the transition from control
to execution with a set of three methods that allocate, transfer, and ready
the data in one operation. These methods all start with the prefix
\textmethod{Prepare} and are meant to be called before some operation happens
in the execution environment. The methods are as follows.

\begin{description}
\item[{\classmember{ArrayHandle}{PrepareForInput}}]
  Copies data from the control to the execution environment, if necessary, and readies the data for read-only access.
\item[{\classmember{ArrayHandle}{PrepareForInPlace}}]
  Copies the data from the control to the execution environment, if necessary, and readies the data for both reading and writing.
\item[{\classmember{ArrayHandle}{PrepareForOutput}}]
  Allocates space (the size of which is given as a parameter) in the execution environment, if necessary, and readies the space for writing.
\end{description}

The \classmember*{ArrayHandle}{PrepareForInput} and \classmember*{ArrayHandle}{PrepareForInPlace} methods each take two arguments.
The first argument is the device adapter tag where execution will take place (see Section~\ref{sec:DeviceAdapterTag} for more information on device adapter tags).
The second argument is a reference to a \vtkmcont{Token}, which scopes the returned array portal.
While the given \textidentifier{Token} exists, the returned portal is guaranteed to be valid and any conflicting operations on the \textidentifier{ArrayHandle} will block.
Once the \textidentifier{Token} is destroyed, the associated array portal becomes invalid.

\classmember*{ArrayHandle}{PrepareForOutput} takes three arguments: the size of the space to allocate, the device adapter tag, and a reference to a \textidentifier{Token} object.

Each of these \textmethod{Prepare} methods returns an array portal that can be used in the execution environment.
\classmember*{ArrayHandle}{PrepareForInput} returns an object of type \classmember{ArrayHandle}{ExecutionTypes}\tparams{{\it{}DeviceAdapterTag}}\textcode{:\colonhyp}\textcode{PortalConst} whereas \textcode{PrepareForInPlace} and \textcode{PrepareForOutput} each return an object of type \classmember{ArrayHandle}{ExecutionTypes}\tparams{{\it{}DeviceAdapterTag}}\textcode{:\colonhyp}\textcode{Portal}.

Although these \textmethod{Prepare} methods are called in the control
environment, the returned array portal can only be used in the execution
environment. Thus, the portal must be passed to an invocation of the
execution environment.

Most of the time, the passing of \textidentifier{ArrayHandle} data to the execution environment is handled automatically by \VTKm.
The most common need to call one of these \textmethod{Prepare} methods is to build execution objects (Chapter \ref{chap:ExecutionObjects}) or to construct derived array types (Section \ref{sec:DerivedStorage}).

The following example is a contrived example for preparing arrays for the execution environment.
It is contrived because it would be easier to create a worklet or transform array handle to have the same effect, and in those cases \VTKm would take of the transfers internally.
More realistic examples can be found in Chapter \ref{chap:ExecutionObjects} and Section \ref{sec:DerivedStorage}.

\vtkmlisting{Using an execution array portal from an \textidentifier{ArrayHandle}.}{ExecutionPortals.cxx}

\begin{commonerrors}
  Once one of the \textmethod{Prepare} methods have been called, further operations on the \textmethod{ArrayHandle} that might cause access hazards will block.
  This opens the possibility of deadlock.
  To help prevent deadlock, the attached \textidentifier{Token} object should be scoped to last only as long as necessary.
\end{commonerrors}

\index{array handle!execution environment|)}

\index{array handle|)}
