Assignment of a general matrix to a submatrix of a symmetrix matrix of different storage order does not compile

Issue #364 resolved
Mikhail Katliar created an issue

Example:

#include <blaze/Math.h>

#include <memory>
#include <iostream>


int main(int, char **)
{
    using namespace blaze;

    SymmetricMatrix<StaticMatrix<double, 3, 3, columnMajor>> H;
    makePositiveDefinite(H);

    StaticMatrix<double, 2, 2, rowMajor> Q;
    makePositiveDefinite(Q);

    submatrix<0, 0, 2, 2>(H) = Q;  // <-- compilation error

    std::cout << "Q = \n" << Q;
    std::cout << "H = \n" << H;

    return 0;
}

Compiler output:

$ g++ -std=c++17 symmetrix_matrix_assign.cpp 
In file included from /usr/local/include/blaze/math/expressions/Matrix.h:44,
                 from /usr/local/include/blaze/math/views/Band.h:54,
                 from /usr/local/include/blaze/math/Band.h:50,
                 from /usr/local/include/blaze/Math.h:46,
                 from symmetrix_matrix_assign.cpp:1:
/usr/local/include/blaze/math/expressions/Matrix.h: In instantiation of ‘blaze::DisableIf_t<IsSymmetric_v<MT2> > blaze::assign_backend(blaze::Matrix<MT, SO>&, const blaze::Matrix<MT2, (! SO)>&) [with MT1 = blaze::Submatrix<blaze::SymmetricMatrix<blaze::StaticMatrix<double, 3, 3, true> >, blaze::unaligned, true, true, 0, 0, 2, 2>; bool SO = true; MT2 = blaze::StaticMatrix<double, 2, 2, false>; blaze::DisableIf_t<IsSymmetric_v<MT2> > = void]’:
/usr/local/include/blaze/math/expressions/Matrix.h:1112:18:   required from ‘void blaze::assign(blaze::Matrix<MT, SO>&, const blaze::Matrix<MT, SO>&) [with MT1 = blaze::Submatrix<blaze::SymmetricMatrix<blaze::StaticMatrix<double, 3, 3, true> >, blaze::unaligned, true, true, 0, 0, 2, 2>; bool SO1 = true; MT2 = blaze::StaticMatrix<double, 2, 2, false>; bool SO2 = false]’
/usr/local/include/blaze/math/smp/default/DenseMatrix.h:108:10:   required from ‘blaze::EnableIf_t<IsDenseMatrix_v<MT1> > blaze::smpAssign(blaze::Matrix<MT, SO>&, const blaze::Matrix<MT, SO>&) [with MT1 = blaze::Submatrix<blaze::SymmetricMatrix<blaze::StaticMatrix<double, 3, 3, true> >, blaze::unaligned, true, true, 0, 0, 2, 2>; bool SO1 = true; MT2 = blaze::StaticMatrix<double, 2, 2, false>; bool SO2 = false; blaze::EnableIf_t<IsDenseMatrix_v<MT1> > = void]’
/usr/local/include/blaze/math/views/submatrix/Dense.h:4691:16:   required from ‘blaze::Submatrix<MT, blaze::unaligned, true, true, CSAs ...>& blaze::Submatrix<MT, blaze::unaligned, true, true, CSAs ...>::operator=(const blaze::Matrix<MT, SO>&) [with MT2 = blaze::StaticMatrix<double, 2, 2, false>; bool SO = false; MT = blaze::SymmetricMatrix<blaze::StaticMatrix<double, 3, 3, true> >; long unsigned int ...CSAs = {0, 0, 2, 2}]’
symmetrix_matrix_assign.cpp:17:32:   required from here
/usr/local/include/blaze/math/expressions/Matrix.h:1052:4: error: static assertion failed: Symmetric matrix type detected
 1052 |    BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE( MT1 );
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The error does not occur if the storage order of H and Q are the same. I would expect the code to compile and work correctly for any combination of storage orders.

Comments (6)

  1. Klaus Iglberger

    Hi Misha!

    Thanks a lot for reporting this problem! Thanks to your minimum example we could easily reproduce the problem. We apologize for the inconvenience and will fix the problem as quickly as possible.

    Best regards,

    Klaus!

  2. Klaus Iglberger

    Commit 95abb15 fixes the (compound) assignment to symmetric submatrices with matrices of different storage order. The fix is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.8.

  3. Log in to comment