Should CustomVector/CustomMatrix support padded const value types?

Issue #161 resolved
magras created an issue

I have aligned and padded const buffer with data. I want to use it as const matrix in blaze:

#include <blaze/math/CustomMatrix.h>
#include <vector>

void ProcessImage(const char* data, unsigned width, unsigned height, unsigned stride)
{
    using MyConstMatrix = blaze::CustomMatrix<const char, blaze::aligned, blaze::padded, blaze::rowMajor>;
    MyConstMatrix image(data, height, width, stride);

    // ...
}

int main()
{
    unsigned width = 9;
    unsigned height = 9;
    unsigned stride = 16;

    std::vector<char> buf(height * stride);

    ProcessImage(buf.data(), width, height, stride);

    return 0;
}

This gives me an error when blaze tries to default initialize padded elements in matrix constructor (msvc 2017):

1>d:\sdk\blaze-3.3\include\blaze\math\dense\custommatrix.h(833): error C2166: l-value specifies const object
1>d:\sdk\blaze-3.3\include\blaze\math\dense\custommatrix.h(813): note: while compiling class template member function 'blaze::CustomMatrix<const char,true,true,false>::CustomMatrix(Type *,::size_t,::size_t,::size_t)'
1>        with
1>        [
1>            Type=const char
1>        ]
1>d:\magras\src\test\msvc15\test3\test3.cpp(7): note: see reference to function template instantiation 'blaze::CustomMatrix<const char,true,true,false>::CustomMatrix(Type *,::size_t,::size_t,::size_t)' being compiled
1>        with
1>        [
1>            Type=const char
1>        ]
1>d:\magras\src\test\msvc15\test3\test3.cpp(7): note: see reference to class template instantiation 'blaze::CustomMatrix<const char,true,true,false>' being compiled
1>d:\sdk\blaze-3.3\include\blaze\math\views\check.h(138): note: see reference to class template instantiation 'blaze::Check<false>' being compiled
1>d:\sdk\blaze-3.3\include\blaze\math\views\check.h(121): note: see reference to class template instantiation 'blaze::Check<true>' being compiled

Is it necessary to initialize them?


I'm using blaze 3.3.

Comments (6)

  1. Klaus Iglberger

    Hi Magras!

    Thanks a lot for raising this issue. You are correct, the code in your example does not compile. The reason is that you are using a blaze::CustomMatrix with blaze::padded parameter:

    using MyConstMatrix = blaze::CustomMatrix<const char, blaze::aligned, blaze::padded, blaze::rowMajor>;
    MyConstMatrix image(data, height, width, stride);  // Padded custom matrix with stride
    

    In order to properly set the padding elements, Blaze needs write access to these elements (see also the wiki). Thus the compilation error is expected. In order to resolve the problem we would recommend to use blaze::unpadded instead:

    using MyConstMatrix = blaze::CustomMatrix<const char, blaze::aligned, blaze::unpadded, blaze::rowMajor>;
    MyConstMatrix image(data, height, width, stride);  // Unpadded custom matrix with stride
    

    Note that it is also possible to specify a stride in this case. Unfortunately this also fails to compile for the same reason: Blaze requires write access to the values. Write access, however, should not be necessary since no elements need to be zero initialized. Therefore this is a problem on our side, which we will fix as quickly as possible. We apologize for the inconvenience. Thanks again for raising this issue,

    Best regards,

    Klaus!

  2. magras reporter

    Hi Klaus!

    Thank you for your answer.

    I read wiki about padding before opening this issue, but it doesn't explain why such initialization required. Sorry if i'm importunate, but i'm really curious why it is required.

  3. Klaus Iglberger

    Summary

    Commit 7a8cdae implements the necessary changes to resolve the compilation error when creating an unpadded CustomMatrix with strided access and constant elements. The fix is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.4.

    Details

    It is now possible to create an unpadded CustomMatrix with strided access and constant elements:

    // Works: Setup of an unpadded custom matrix with strided access and const elements
    using MyConstMatrix = blaze::CustomMatrix<const char, blaze::aligned, blaze::unpadded, blaze::rowMajor>;
    MyConstMatrix image(data, height, width, stride);
    

    Note however that the changes only affect unpadded matrices. In the case of padded CustomMatrix instances, write access is still required to guarantee that the padding elements are zero initialized:

    // Compilation error: Setup of a padded custom matrix with constant elements; Write access to the elements is required
    using MyConstMatrix = blaze::CustomMatrix<const char, blaze::aligned, blaze::padded, blaze::rowMajor>;
    MyConstMatrix image(data, height, width, stride);
    

    The zero initialization is required by several algorithms (e.g. reduction operations) and also avoids the problem of denormalized numbers that could have a significant effect on performance.

  4. Log in to comment