Custom allocation

Issue #307 resolved
Matthias Moulin created an issue

Currently, Blaze manages and encapsulates allocation and deallocation of vectors/matrices internally. Pre C++17, this is a necessity as class member operator new/new[]/delete/delete[] need to ensure correct alignment on the heap (not only on the stack). Once Blaze transitions to C++17, the use of alignas will ensure correct alignment on the stack and heap. Therefore, there is no need anymore for class member operator new/new[]/delete/delete[] and one can just fallback to global operator new/new[]/delete/delete[] (e.g., std::align_val_t). Furthermore, the latter facilitates the possibility of optionally using a Blaze-external implementation of these global operators (to centralize memory management across dependencies).

Comments (4)

  1. Klaus Iglberger

    Hi Matthias!

    Thanks a lot for creating this issue. You have spelled out a very important topic that we have been working on for some time now. Thus you can expect some changes in this regard even before we make the transition to C++17. Thanks again,

    Best regards,

    Klaus!

  2. Klaus Iglberger

    Summary

    With commits c7676e2 and d9053fa both blaze::DynamicVector and blaze::DynamicMatrix have been extended by a third template parameter. Via this template parameter it is possible to customize the memory allocation. The feature is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.8.

    DynamicVector

    The blaze::DynamicVector class template is the representation of an arbitrarily sized vector with dynamically allocated elements of arbitrary type. It can be included via the header files

    #include <blaze/Blaze.h>
    // or
    #include <blaze/Math.h>
    // or
    #include <blaze/math/DynamicVector.h>
    

    and forward declared via the header file

    #include <blaze/Forward.h>
    

    The type of the elements, the transpose flag, the type of the allocator, and the group tag of the vector can be specified via the three template parameters:

    namespace blaze {
    
    template< typename Type, bool TF, typename Alloc, typename Tag >
    class DynamicVector;
    
    } // namespace blaze
    
    • Type : specifies the type of the vector elements. DynamicVector can be used with any non-cv-qualified element type, including other vector or matrix types.
    • TF : specifies whether the vector is a row vector (blaze::rowVector) or a column vector (blaze::columnVector). The default value is blaze::defaultTransposeFlag.
    • Alloc : specifies the type of allocator used to allocate dynamic memory. The default type of allocator is blaze::AlignedAllocator.
    • Tag : optional type parameter to tag the vector. The default type is blaze::Group0. See [[Grouping-Tagging|Grouping/Tagging]] for details.

    The blaze::DynamicVector is the default choice for all kinds of dense vectors and the best choice for medium to large vectors. Its size can be modified at runtime:

    // Definition of a 3-dimensional integral column vector
    blaze::DynamicVector<int> a( 3UL );
    
    // Definition of a 4-dimensional single precision column vector
    blaze::DynamicVector<float,blaze::columnVector> b( 4UL );
    
    // Definition of a double precision row vector with size 0
    blaze::DynamicVector<double,blaze::rowVector> c;
    

    Allocators

    Via the third template parameter it is possible to customize the memory allocation of a blaze::DynamicVector. The provided allocator is expected to represent an implementation of the allocator concept of the standard library (see for instance std::vector and std::allocator). In addition, the provided allocator is also required to provide properly (over-)aligned memory for fundamental and complex numbers. For instance, in case SSE vectorization is possible, the returned memory must be at least 16-byte aligned. In case AVX is active, the memory must be at least 32-byte aligned, and in case of AVX-512 the memory must be even 64-byte aligned.

    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 files

    #include <blaze/Blaze.h>
    // or
    #include <blaze/Math.h>
    // or
    #include <blaze/math/DynamicMatrix.h>
    

    and forward declared via the header file

    #include <blaze/Forward.h>
    

    The type of the elements, the storage order, the type of the allocator, and the group tag of the matrix can be specified via the three template parameters:

    namespace blaze {
    
    template< typename Type, bool SO, typename Alloc, typename Tag >
    class DynamicMatrix;
    
    } // namespace blaze
    
    • 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::defaultStorageOrder.
    • Alloc : specifies the type of allocator used to allocate dynamic memory. The default type of allocator is blaze::AlignedAllocator.
    • Tag : optional type parameter to tag the matrix. The default type is blaze::Group0. See [[Grouping-Tagging|Grouping/Tagging]] for details.

    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;
    

    Allocators

    Via the third template parameter it is possible to customize the memory allocation of a blaze::DynamicMatrix. The provided allocator is expected to represent an implementation of the allocator concept of the standard library (see for instance std::vector and std::allocator). In addition, the provided allocator is also required to provide properly (over-)aligned memory for fundamental and complex numbers. For instance, in case SSE vectorization is possible, the returned memory must be at least 16-byte aligned. In case AVX is active, the memory must be at least 32-byte aligned, and in case of AVX-512 the memory must be even 64-byte aligned.

  3. Log in to comment