Basic Types

HighFM currently offers the following types:

Template Parameters:

All types share the same template parameters:

template<Number ElemType, DataLocation Location, template<typename, typename> typename Storage>
class Vector;

where ElemType is the data type of entries in the container (double or float), Location determines where the data is located (i.e, on the Host or on the Device) and the Storage indicates the container used for storing the object in memory. Currently, HighFM supports two Storage types: Array and DataMap.

Array represents a plain contiguous array that has its memory allocation automatically managed by the HighFM library. This allows the size of the container (and the underlying memory allocation) to be changed at will, similarly to the std::vector from the STL. It is recommended to use this container when constructing new types.

Note

The resize() method is destructive (i.e., all previous content will be clear when resizing the container).

DataMap, on the other hand, represent a map to an existing memory allocation, essentially, wrapping a pointer and its size as a HighFM container. Since the memory allocation is managed externally, the size of the container is fixed. The DataMap can be remapped to another container using the map_to() method. This storage type should be used for either wrapping data generated by external libraries or manipulating data slices.

For example, Vector<float, Host, Array> indicates a dense vector of float entries that is located in the Host and uses the Array container for storing the data. In this case, you can just write Vector<float> as the default Location is the Host and the default Storage is the Array. The other types follow the same rules.

Capacity:

  • The number of rows and columns for any vector or matrix can be retrieved by calling the rows() and cols() methods, respectively.

  • The size() routine returns either the number of entries when working with dense objects or the number of nonzero elements when working with sparse objects.

Element Access and Slicing:

  • Individual entries in the container can be accessed using the operators [] and ().

  • Most containers also support slicing, i.e., creating a map to some part of the matrix or vector. This is typically achieved by specifying a Range or using the kAll tag. The Range object has the following structure:

struct Range

A (contiguous) range of entries in the container.

Public Functions

inline index_t size() const

Size of the range.

Public Members

index_t begin

Index of the first element in container.

index_t end

Index of the last element in the container (not included)

Note that you can construct the Range object in place, e.g., vec({2, 6}) constructs a slice that spans the entries 2 to 6 of the vector vec.

Assignment:

  • All data types support the assignment operator = to copy data between two objects. This operator is also used for converting from sparse to dense vectors/matrices as well as for evaluating BLAS/LAPACK expressions.

  • If the source container is located in the host and the destination, in the device, or vice-versa, this will imply a data transfer between the two memory spaces.

  • There is no move assignment or constructor for the DataMap. Let us consider the following code

MatrixMap<double> mat1;
Matrix<double> mat2;

mat1 = mat2({0, 5}, {0, 5})

If the move assignment operator is specified, then submatrix mat2({0, 5}, {0, 5}) will be moved to the mat1, replacing its memory allocation. However, in this case, we expect the data to be copied from one matrix to another. To avoid this ambiguity, we reserve the = operator exclusively for copying data when dealing with slices and DataMap. The Array does not have this restriction.

Compatibility

To have maximum compatibility with other libraries, all HighFM objects can be reduced to a simple, compact struct that only contains the pointer to the beginning of the container as well as additional information related to the object (e.g., number of rows, number of columns, leading dimension, etc.). For instance, the struct associated with a Matrix is

template<typename T>
struct MatrixData

A simple struct storing the data of a dense matrix in the column-major format.

Public Members

T *buffer

A contiguous array with elements of the matrix.

index_t nrows

Number of rows in the matrix.

index_t ncols

Number of columns in the matrix.

index_t lead_dim

Leading dimension of the matrix (i.e., the distance between the first element in each column)

To retrieve the compact struct from an existing object obj, you can call the obj.matrix_data() method. Note that, besides changing the values within the container, any modification to a member of the struct will not be reflected in the original object (e.g., changing the number of rows or columns). The compact struct can also be used for constructing new HighFM objects.