% -*- latex -*-

\chapter{Base Types}
\label{chap:BaseTypes}

It is common for a framework to define its own types.
Even the C++ standard template library defines its own base types like \textcode{std::size\_t} and \textcode{std::pair}.
\VTKm is no exception.

In fact \VTKm provides a great many base types.
It is the general coding standard of \VTKm to not directly use the base C types like \textcode{int} and \textcode{float} and instead to use types declared in \VTKm.
The rational is to precisely declare the representation of each variable to prevent future trouble.

Consider that you are programming something and you need to declare an integer variable.
You would declare this variable as \index{int}\textcode{int}, right?
Well, maybe.
In C++, the declaration \textcode{int} does not simply mean ``an integer.''
\textcode{int} means something much more specific than that.
If you were to look up the C++11 standard, you would find that \textcode{int} is an integer represented in 32 bits with a two's complement signed representation.
In fact, a C++ compiler has no less than 8 standard integer types.%
\footnote{%
  I intentionally use the phrase ``no less than'' for our pedantic readers.
  One could argue that \textcode{char} and \textcode{bool} are treated distinctly by the compiler even if their representations match either \textcode{signed char} or \textcode{unsigned char}.
  Furthermore, many modern C++ compilers have extensions for less universally accepted types like 128-bit integers.
}

So, \textcode{int} is nowhere near as general as the code might make it seem, and treating it as such could lead to trouble.
For example, consider the MPI standard, which, back in the 1990's, implicitly selected \textcode{int} for its indexing needs.
Fast forward to today where there is a need to reference buffers with more than 2 billion elements, but the standard is stuck with a data type that cannot represent sizes that big.%
\footnote{%
  To be fair, it is \emph{possible} to represent buffers this large in MPI, but it is extraordinarily awkward to do so.
}

Consequently, we feel that with \VTKm it is best to declare the intention of a variable with its declaration, which should help both prevent errors and future proof code.
All the types presented in this chapter are declared in \vtkmheader{vtkm}{Types.h}, which is typically included either directly or indirectly by all source using \VTKm.


\section{Floating Point Types}
\label{sec:FloatingTypes}

\VTKm declares 2 types to hold floating point numbers: \vtkm{Float32} and \vtkm{Float64}.
These, of course, represent floating point numbers with 32-bits and 64-bits of precision, respectively.
These should be used when the precision of a floating point number is predetermined.

When the precision of a floating point number is not predetermined, operations usually have to be overloaded or templated to work with multiple precisions.
In cases where a precision must be set, but no particular precision is specified, \vtkm{FloatDefault} should be used.
\vtkm{FloatDefault} will be set to either \vtkm{Float32} or \vtkm{Float64} depending on whether the CMake option \cmakevar{VTKM\_USE\_DOUBLE\_PRECISION} was set when \VTKm was compiled, as discussed in Section \ref{sec:ConfigureVTKm}.
Using \vtkm{FloatDefault} makes it easier for users to trade off precision and speed.


\section{Integer Types}
\label{sec:IntegerTypes}

The most common use of an integer in \VTKm is to index arrays.
For this purpose, the \vtkm{Id} type should be used.
(The width of \vtkm{Id} is determined by the \cmakevar{VTKm\_USE\_64BIT\_IDS} CMake option.)

\VTKm also has a secondary index type named \vtkm{IdComponent}, which is smaller and typically used for indexing groups of components within a thread.
For example, if you had an array of 3D points, you would use \vtkm{Id} to reference each point, and you would use \vtkm{IdComponent} to reference the respective $x$, $y$, and $z$ components.


\begin{didyouknow}
  The \VTKm index types, \vtkm{Id} and \vtkm{IdComponent} use signed integers.
  This breaks with the convention of other common index types like the C++ standard template library \index{size\_t}\textcode{std::size\_t}, which use unsigned integers.
  Unsigned integers make sense for indices as a valid index is always 0 or greater.
  However, doing things like iterating in a for loop backward, representing relative indices, and representing invalid values is much easier with signed integers.
  Thus, \VTKm chooses to use a signed integer for indexing.
\end{didyouknow}

\VTKm also has types to declare an integer of a specific width and sign.
The types \vtkm{Int8}, \vtkm{Int16}, \vtkm{Int32}, and \vtkm{Int64} specify signed integers of 1, 2, 4, and 8 bytes, respectively.
Likewise, the types \vtkm{UInt8}, \vtkm{UInt16}, \vtkm{UInt32}, and \vtkm{UInt64} specify unsigned integers of 1, 2, 4, and 8 bytes, respectively.

\section{Vector Types}
\label{sec:VectorTypes}

Visualization algorithms also often require operations on short vectors.
Arrays indexed in up to three dimensions are common.
Data are often defined in 2-space and 3-space, and transformations are typically done in homogeneous coordinates of length 4.
To simplify these types of operations, \VTKm provides a collection of base types to represent these short vectors, which are collectively referred to as \textidentifier{Vec} types.

\vtkm{Vec2f}, \vtkm{Vec3f}, and \vtkm{Vec4f} specify floating point \textidentifier{Vec}s of 2, 3, and 4 components, respectively.
The precision of the floating point numbers follows that of \vtkm{FloatDefault} (which, from what is said in Section \ref{sec:FloatingTypes}, is specified by the \cmakevar{VTKm\_USE\_DOUBLE\_PRECISION} compile option).
Components of these and other \textidentifier{Vec} types can be references through the \textcode{[ ]} operator, much like a C array.
\textidentifier{Vec}s also support basic arithmetic operators so that they can be used much like their scalar-value counterparts.

\vtkmlisting{Simple use of \textidentifier{Vec} objects.}{SimpleVectorTypes.cxx}

You can also specify the precision for each of these vector types by appending the bit size of each component.
For example, \vtkm{Vec3f\_32} and \vtkm{Vec3f\_64} represent 3-component floating point vectors with each component being 32 bits and 64 bits respectively.
Note that the precision number refers to the precision of each component, not the vector as a whole.
So \vtkm{Vec3f\_32} contains 3 32-bit (4-byte) floating point components, which means the entire \vtkm{Vec3f\_32} requires 96 bits (12 bytes).

To help with indexing 2-, 3-, and 4- dimensional arrays, \VTKm provides the types \vtkm{Id2}, \vtkm{Id3}, and \vtkm{Id4}, which are \textidentifier{Vec}s of type \vtkm{Id}.
Likewise, \VTKm provides \vtkm{IdComponent2}, \vtkm{IdComponent3}, and \vtkm{IdComponent4}.

\VTKm also provides types for \textidentifier{Vec}s of integers of all varieties described in Section \ref{sec:IntegerTypes}.
\vtkm{Vec2i}, \vtkm{Vec3i}, and \vtkm{Vec4i} are vectors of signed integers whereas \vtkm{Vec2ui}, \vtkm{Vec3ui}, and \vtkm{Vec4ui} are vectors of unsigned integers.
All of these sport components of a width equal to \vtkm{Id}.
The width can be specified by appending the desired number of bits in the same way as the floating point \textidentifier{Vec}s.
For example, \vtkm{Vec4ui\_8} is a \textidentifier{Vec} of 4 unsigned bytes.

These types really just scratch the surface of the \textidentifier{Vec} types available in \VTKm and the things that can be done with them.
See Chapter \ref{chap:AdvancedTypes} for more information on \textidentifier{Vec} types and what can be done with them.
