==================== Basic Types ==================== HighFM currently offers the following types: .. toctree:: :maxdepth: 1 ../api/types/matrixbase ../api/types/array ../api/types/datamap ../api/types/vector ../api/types/matrix ../api/types/sparse-vector ../api/types/coo ../api/types/csr ../api/types/triangular Template Parameters: -------------------- All types share the same template parameters:: template 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: :ref:`api_array` and :ref:`api_datamap`. :ref:`api_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). :ref:`api_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 :ref:`api_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`` indicates a dense vector of ``float`` entries that is located in the ``Host`` and uses the :ref:`api_array` container for storing the data. In this case, you can just write ``Vector`` 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: .. doxygenstruct:: HighFM::Range :project: HighFM :members: 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 :ref:`api_datamap`. Let us consider the following code .. code:: cpp MatrixMap mat1; Matrix 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 :ref:`api_datamap`. The :ref:`api_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 any information related to the object (e.g., number of rows, number of columns, leading dimension, etc.). For instance, the struct associated with a :ref:`api_dense_matrix` is .. doxygenstruct:: HighFM::MatrixData :project: HighFM :members: 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.