Clone wiki

blaze / Matrix Types


StaticMatrix

The blaze::StaticMatrix class template is the representation of a fixed size matrix with statically allocated elements of arbitrary type. It can be included via the header file

#include <blaze/math/StaticMatrix.h>

The type of the elements, the number of rows and columns, and the storage order of the matrix can be specified via the four template parameters:

template< typename Type, size_t M, size_t N, bool SO >
class StaticMatrix;
  • Type : specifies the type of the matrix elements. StaticMatrix can be used with any non-cv-qualified element type, including vector and other matrix types.
  • M : specifies the total number of rows of the matrix.
  • N : specifies the total number of columns of the matrix. Note that it is expected that StaticMatrix is only used for tiny and small matrices.
  • SO : specifies the storage order (blaze::rowMajor, blaze::columnMajor) of the matrix. The default value is blaze::rowMajor.

The blaze::StaticMatrix is perfectly suited for small to medium matrices whose dimensions are known at compile time:

// Definition of a 3x4 integral row-major matrix
blaze::StaticMatrix<int,3UL,4UL> A;

// Definition of a 4x6 single precision row-major matrix
blaze::StaticMatrix<float,4UL,6UL,blaze::rowMajor> B;

// Definition of a 6x4 double precision column-major matrix
blaze::StaticMatrix<double,6UL,4UL,blaze::columnMajor> C;

DynamicMatrix

The blaze::DynamicMatrix class template is the representation of an arbitrary sized matrix with MxN dynamically allocated elements of arbitrary type. It can be included via the header file

#include <blaze/math/DynamicMatrix.h>

The type of the elements and the storage order of the matrix can be specified via the two template parameters:

template< typename Type, bool SO >
class DynamicMatrix;
  • Type : specifies the type of the matrix elements. DynamicMatrix can be used with any non-cv-qualified element type (even with vector and other matrix types).
  • SO : specifies the storage order (blaze::rowMajor, blaze::columnMajor) of the matrix. The default value is blaze::rowMajor.

The blaze::DynamicMatrix is the default choice for all kinds of dense matrices and the best choice for medium to large matrices. The number of rows and columns can be modified at runtime:

// Definition of a 3x4 integral row-major matrix
blaze::DynamicMatrix<int> A( 3UL, 4UL );

// Definition of a 4x6 single precision row-major matrix
blaze::DynamicMatrix<float,blaze::rowMajor> B( 4UL, 6UL );

// Definition of a double precision column-major matrix with 0 rows and columns
blaze::DynamicMatrix<double,blaze::columnMajor> C;

HybridMatrix

The blaze::HybridMatrix class template combines the flexibility of a dynamically sized matrix with the efficiency and performance of a fixed size matrix. It is implemented as a crossing between the blaze::StaticMatrix and the blaze::DynamicMatrix class templates: Similar to the static matrix it uses static stack memory instead of dynamically allocated memory and similar to the dynamic matrix it can be resized (within the extend of the static memory). It can be included via the header file

#include <blaze/math/HybridMatrix.h>

The type of the elements, the maximum number of rows and columns and the storage order of the matrix can be specified via the four template parameters:

template< typename Type, size_t M, size_t N, bool SO >
class HybridMatrix;
  • Type : specifies the type of the matrix elements. HybridMatrix can be used with any non-cv-qualified, non-reference, non-pointer element type.
  • M : specifies the maximum number of rows of the matrix.
  • N : specifies the maximum number of columns of the matrix. Note that it is expected that HybridMatrix is only used for tiny and small matrices.
  • SO : specifies the storage order (blaze::rowMajor, blaze::columnMajor) of the matrix. The default value is blaze::rowMajor.

The blaze::HybridMatrix is a suitable choice for small to medium matrices, whose dimensions are not known at compile time or not fixed at runtime, but whose maximum dimensions are known at compile time:

// Definition of a 3x4 integral row-major matrix with maximum dimensions of 6x8
blaze::HybridMatrix<int,6UL,8UL> A( 3UL, 4UL );

// Definition of a 4x6 single precision row-major matrix with maximum dimensions of 12x16
blaze::HybridMatrix<float,12UL,16UL,blaze::rowMajor> B( 4UL, 6UL );

// Definition of a 0x0 double precision column-major matrix and maximum dimensions of 6x6
blaze::HybridMatrix<double,6UL,6UL,blaze::columnMajor> C;

CustomMatrix

The blaze::CustomMatrix class template provides the functionality to represent an external array of elements of arbitrary type and a fixed size as a native Blaze dense matrix data structure. Thus in contrast to all other dense matrix types a custom matrix does not perform any kind of memory allocation by itself, but it is provided with an existing array of element during construction. A custom matrix can therefore be considered an alias to the existing array. It can be included via the header file

#include <blaze/math/CustomMatrix.h>

The type of the elements, the properties of the given array of elements and the storage order of the matrix can be specified via the following four template parameters:

template< typename Type, bool AF, bool PF, bool SO >
class CustomMatrix;
  • Type : specifies the type of the matrix elements. CustomMatrix can be used with any non-cv-qualified, non-reference, non-pointer element type.
  • AF : specifies whether the represented, external arrays are properly aligned with respect to the available instruction set (SSE, AVX, ...) or not.
  • PF : specified whether the represented, external arrays are properly padded with respect to the available instruction set (SSE, AVX, ...) or not.
  • SO : specifies the storage order (blaze::rowMajor, blaze::columnMajor) of the matrix. The default value is blaze::rowMajor.

The blaze::CustomMatrix is the right choice if any external array needs to be represented as a Blaze dense matrix data structure or if a custom memory allocation strategy needs to be realized:

using blaze::CustomMatrix;
using blaze::Deallocate;
using blaze::aligned;
using blaze::unaligned;
using blaze::padded;
using blaze::unpadded;

// Definition of an unmanaged 3x4 custom matrix for unaligned, unpadded integer arrays
using UnalignedUnpadded = CustomMatrix<int,unaligned,unpadded,rowMajor>;
std::vector<int> vec( 12UL )
UnalignedUnpadded A( &vec[0], 3UL, 4UL );

// Definition of a managed 5x6 custom matrix for unaligned but padded 'float' arrays
using UnalignedPadded = CustomMatrix<float,unaligned,padded,columnMajor>;
std::unique_ptr<float[]> memory1( new float[40] );
UnalignedPadded B( memory1.get(), 5UL, 6UL, 8UL );

// Definition of a managed 12x13 custom matrix for aligned, unpadded 'double' arrays
using AlignedUnpadded = CustomMatrix<double,aligned,unpadded,rowMajor>;
std::unique_ptr<double[],Deallocate> memory2( blaze::allocate<double>( 192UL ) );
AlignedUnpadded C( memory2.get(), 12UL, 13UL, 16UL );

// Definition of a 7x14 custom matrix for aligned, padded 'complex<double>' arrays
using cplx = complex<double>;
using AlignedPadded = CustomMatrix<cplx,aligned,padded,columnMajor>;
std::unique_ptr<cplx[],Deallocate> memory3( blaze::allocate<cplx>( 112UL ) );
AlignedPadded D( memory3.get(), 7UL, 14UL, 16UL );

In comparison with the remaining Blaze dense matrix types CustomMatrix has several special characteristics. All of these result from the fact that a custom matrix is not performing any kind of memory allocation, but instead is given an existing array of elements. The following sections discuss all of these characteristics:

Memory Management

The CustomMatrix class template acts as an adaptor for an existing array of elements. As such it provides everything that is required to use the array just like a native Blaze dense matrix data structure. However, this flexibility comes with the price that the user of a custom matrix is responsible for the resource management.

The following examples give an impression of several possible types of custom matrices:

using blaze::CustomMatrix;
using blaze::Deallocate;
using blaze::allocate;
using blaze::aligned;
using blaze::unaligned;
using blaze::padded;
using blaze::unpadded;

// Definition of a 3x4 custom row-major matrix with unaligned, unpadded and externally
// managed integer array. Note that the std::vector must be guaranteed to outlive the
// custom matrix!
std::vector<int> vec( 12UL );
CustomMatrix<int,unaligned,unpadded> A( &vec[0], 3UL, 4UL );

// Definition of a custom 8x12 matrix for an aligned and padded integer array of
// capacity 128 (including 8 padding elements per row). Note that the std::unique_ptr
// must be guaranteed to outlive the custom matrix!
std::unique_ptr<int[],Deallocate> memory( allocate<int>( 128UL ) );
CustomMatrix<int,aligned,padded> B( memory.get(), 8UL, 12UL, 16UL );

Copy Operations

As with all dense matrices it is possible to copy construct a custom matrix:

using blaze::CustomMatrix;
using blaze::unaligned;
using blaze::unpadded;

using CustomType = CustomMatrix<int,unaligned,unpadded>;

std::vector<int> vec( 6UL, 10 );    // Vector of 6 integers of the value 10
CustomType A( &vec[0], 2UL, 3UL );  // Represent the std::vector as Blaze dense matrix
a[1] = 20;                          // Also modifies the std::vector

CustomType B( a );  // Creating a copy of vector a
b[2] = 20;          // Also affects matrix A and the std::vector

It is important to note that a custom matrix acts as a reference to the specified array. Thus the result of the copy constructor is a new custom matrix that is referencing and representing the same array as the original custom matrix.

In contrast to copy construction, just as with references, copy assignment does not change which array is referenced by the custom matrices, but modifies the values of the array:

std::vector<int> vec2( 6UL, 4 );     // Vector of 6 integers of the value 4
CustomType C( &vec2[0], 2UL, 3UL );  // Represent the std::vector as Blaze dense matrix

A = C;  // Copy assignment: Set all values of matrix A and B to 4.

Alignment

In case the custom matrix is specified as aligned the passed array must adhere to some alignment restrictions based on the alignment requirements of the used data type and the used instruction set (SSE, AVX, ...). The restriction applies to the first element of each row/column: In case of a row-major matrix the first element of each row must be properly aligned, in case of a column-major matrix the first element of each column must be properly aligned. For instance, if a row-major matrix is used and AVX is active the first element of each row must be 32-bit aligned:

using blaze::CustomMatrix;
using blaze::Deallocate;
using blaze::allocate;
using blaze::aligned;
using blaze::padded;
using blaze::rowMajor;

// Allocation of 32-bit aligned memory
std::unique_ptr<int[],Deallocate> memory( allocate<int>( 40UL ) );

CustomMatrix<int,aligned,padded,rowMajor> A( memory.get(), 5UL, 6UL, 8UL );

In the example, the row-major matrix has six columns. However, since with AVX eight integer values are loaded together the matrix is padded with two additional elements. This guarantees that the first element of each row is 32-bit aligned. In case the alignment requirements are violated, a std::invalid_argument exception is thrown.

Padding

Adding padding elements to the end of each row/column can have a significant impact on the performance. For instance, assuming that AVX is available, then two aligned, padded, 3x3 double precision matrices can be added via three SIMD addition instruction:

using blaze::CustomMatrix;
using blaze::Deallocate;
using blaze::allocate;
using blaze::aligned;
using blaze::padded;

using CustomType = CustomMatrix<double,aligned,padded>;

std::unique_ptr<int[],Deallocate> memory1( allocate<double>( 12UL ) );
std::unique_ptr<int[],Deallocate> memory2( allocate<double>( 12UL ) );
std::unique_ptr<int[],Deallocate> memory3( allocate<double>( 12UL ) );

// Creating padded custom 3x3 matrix with an additional padding element in each row
CustomType A( memory1.get(), 3UL, 3UL, 4UL );
CustomType B( memory2.get(), 3UL, 3UL, 4UL );
CustomType C( memory3.get(), 3UL, 3UL, 4UL );

// ... Initialization

C = A + B;  // AVX-based matrix addition

In this example, maximum performance is possible. However, in case no padding elements are inserted a scalar addition has to be used:

using blaze::CustomMatrix;
using blaze::Deallocate;
using blaze::allocate;
using blaze::aligned;
using blaze::unpadded;

using CustomType = CustomMatrix<double,aligned,unpadded>;

std::unique_ptr<int[],Deallocate> memory1( allocate<double>( 9UL ) );
std::unique_ptr<int[],Deallocate> memory2( allocate<double>( 9UL ) );
std::unique_ptr<int[],Deallocate> memory3( allocate<double>( 9UL ) );

// Creating unpadded custom 3x3 matrix
CustomType A( memory1.get(), 3UL, 3UL );
CustomType B( memory2.get(), 3UL, 3UL );
CustomType C( memory3.get(), 3UL, 3UL );

// ... Initialization

C = A + B;  // Scalar matrix addition

Note that the construction of padded and unpadded aligned matrices looks identical. However, in case of padded matrices, Blaze will zero initialize the padding element and use them in all computations in order to achieve maximum performance. In case of an unpadded matrix Blaze will ignore the elements with the downside that it is not possible to load a complete row to an AVX register, which makes it necessary to fall back to a scalar addition.

The number of padding elements is required to be sufficient with respect to the available instruction set: In case of an aligned padded custom matrix the added padding elements must guarantee that the total number of elements in each row/column is a multiple of the SIMD vector width. In case of an unaligned padded matrix the number of padding elements can be greater or equal the number of padding elements of an aligned padded custom matrix. In case the padding is insufficient with respect to the available instruction set, a std::invalid_argument exception is thrown.


CompressedMatrix

The blaze::CompressedMatrix class template is the representation of an arbitrary sized sparse matrix with MxN dynamically allocated elements of arbitrary type. It can be included via the header file

#include <blaze/math/CompressedMatrix.h>

The type of the elements and the storage order of the matrix can be specified via the two template parameters:

template< typename Type, bool SO >
class CompressedMatrix;
  • Type : specifies the type of the matrix elements. CompressedMatrix can be used with any non-cv-qualified element type (including vector and other matrix types).
  • SO : specifies the storage order (blaze::rowMajor, blaze::columnMajor) of the matrix. The default value is blaze::rowMajor.

The blaze::CompressedMatrix is the right choice for all kinds of sparse matrices:

// Definition of a 3x4 integral row-major matrix
blaze::CompressedMatrix<int> A( 3UL, 4UL );

// Definition of a 4x6 single precision row-major matrix
blaze::CompressedMatrix<float,blaze::rowMajor> B( 4UL, 6UL );

// Definition of a double precision column-major matrix with 0 rows and columns
blaze::CompressedMatrix<double,blaze::columnMajor> C;

IdentityMatrix

The blaze::IdentityMatrix class template is the representation of an immutable, arbitrary sized identity matrix with NxN elements of arbitrary type. It can be included via the header file

#include <blaze/math/IdentityMatrix.h>

The type of the elements and the storage order of the matrix can be specified via the two template parameters:

template< typename Type, bool SO >
class IdentityMatrix;
  • Type : specifies the type of the matrix elements. IdentityMatrix can be used with any non-cv-qualified, non-reference, non-pointer element type.
  • SO : specifies the storage order (blaze::rowMajor, blaze::columnMajor) of the matrix. The default value is blaze::rowMajor.

The blaze::IdentityMatrix is the perfect choice to represent an identity matrix:

// Definition of a 3x3 integral row-major identity matrix
blaze::IdentityMatrix<int> A( 3UL );

// Definition of a 6x6 single precision row-major identity matrix
blaze::IdentityMatrix<float,blaze::rowMajor> B( 6UL );

// Definition of a double precision column-major identity matrix with 0 rows and columns
blaze::IdentityMatrix<double,blaze::columnMajor> C;

Previous: Matrices ---- Next: Matrix Operations

Updated