Valid matrix expression does not compile

Issue #334 resolved
Mikhail Katliar created an issue

Example:

#include <blaze/Math.h>


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

    size_t constexpr NX = 13;
    size_t constexpr NU = 8;
    size_t constexpr NY = 9;

    DynamicMatrix<double, rowMajor> J(NX, NX + NU); // <-- If rowMajor is changed to columnMajor, the code compiles
    DiagonalMatrix<StaticMatrix<double, NY, NY, columnMajor>> W;
    StaticMatrix<double, NY, NU, columnMajor> B;

    submatrix<0, NX, NY, NU>(J) += W * B;

    return 0;
}

Compiler command line:

g++ --std=c++17 test.cpp

Compiler output (g++ 9.2.1):

In file included from /home/kotlyar/software/blaze/blaze/math/views/band/Dense.h:49,
                 from /home/kotlyar/software/blaze/blaze/math/views/Band.h:76,
                 from /home/kotlyar/software/blaze/blaze/math/Band.h:50,
                 from /home/kotlyar/software/blaze/blaze/Math.h:46,
                 from test.cpp:1:
/home/kotlyar/software/blaze/blaze/math/expressions/DMatDMatMultExpr.h: In instantiation of ‘class blaze::DMatDMatMultExpr<blaze::DMatTransExpr<blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >, false>, blaze::DMatTransExpr<blaze::StaticMatrix<double, 9, 8, true>, false>, false, false, false, false>’:
/home/kotlyar/software/blaze/blaze/math/expressions/DMatDMatMultExpr.h:9691:11:   required from ‘decltype(auto) blaze::operator*(const blaze::DenseMatrix<MT1, false>&, const blaze::DenseMatrix<MT2, false>&) [with MT1 = blaze::DMatTransExpr<blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >, false>; MT2 = blaze::DMatTransExpr<blaze::StaticMatrix<double, 9, 8, true>, false>]’
/home/kotlyar/software/blaze/blaze/math/expressions/TDMatTDMatMultExpr.h:4652:53:   required from ‘blaze::EnableIf_t<CanExploitSymmetry_v<MT, MT1, MT2> > blaze::smpAddAssign(blaze::Matrix<MT, false>&, const blaze::TDMatTDMatMultExpr< <template-parameter-1-1>, <template-parameter-1-2>, <anonymous>, <anonymous>, <anonymous>, <anonymous> >&) [with MT = blaze::Submatrix<blaze::DynamicMatrix<double, false>, blaze::unaligned, false, true, 0, 13, 9, 8>; MT1 = blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >; MT2 = blaze::StaticMatrix<double, 9, 8, true>; bool SF = false; bool HF = false; bool LF = false; bool UF = false; blaze::EnableIf_t<CanExploitSymmetry_v<MT, MT1, MT2> > = void]’
/home/kotlyar/software/blaze/blaze/math/views/submatrix/Dense.h:1499:19:   required from ‘blaze::DisableIf_t<EnforceEvaluation_v<MT, MT2>, blaze::Submatrix<MT, blaze::unaligned, false, true, CSAs ...>&> blaze::Submatrix<MT, blaze::unaligned, false, true, CSAs ...>::operator+=(const blaze::Matrix<MT, SO>&) [with MT2 = blaze::TDMatTDMatMultExpr<blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >, blaze::StaticMatrix<double, 9, 8, true>, false, false, false, false>; bool SO2 = true; MT = blaze::DynamicMatrix<double, false>; long unsigned int ...CSAs = {0, 13, 9, 8}; blaze::DisableIf_t<EnforceEvaluation_v<MT, MT2>, blaze::Submatrix<MT, blaze::unaligned, false, true, CSAs ...>&> = blaze::Submatrix<blaze::DynamicMatrix<double, false>, blaze::unaligned, false, true, 0, 13, 9, 8>&]’
test.cpp:18:40:   required from here
/home/kotlyar/software/blaze/blaze/math/constraints/MatMatMultExpr.h:105:43: error: static assertion failed: Invalid matrix/matrix multiplication expression detected
  104 |    static_assert( ::blaze::IsMatrix_v<T1> && \
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  105 |                   ::blaze::IsMatrix_v<T2> && \
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~
  106 |                   ( ( ::blaze::Size_v<T1,1UL> == -1L ) || \
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  107 |                     ( ::blaze::Size_v<T2,0UL> == -1L ) || \
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  108 |                     ( ::blaze::Size_v<T1,1UL> == ::blaze::Size_v<T2,0UL> ) ) \
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/kotlyar/software/blaze/blaze/math/expressions/DMatDMatMultExpr.h:4798:4: note: in expansion of macro ‘BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR’
 4798 |    BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR( MT1, MT2 );
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/kotlyar/software/blaze/blaze/math/expressions/TDMatDMatMultExpr.h: In instantiation of ‘class blaze::TDMatDMatMultExpr<blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >, blaze::DMatTransExpr<blaze::StaticMatrix<double, 9, 8, true>, false>, false, false, false, false>’:
/home/kotlyar/software/blaze/blaze/math/expressions/TDMatDMatMultExpr.h:14737:11:   required from ‘decltype(auto) blaze::operator*(const blaze::DenseMatrix<MT1, true>&, const blaze::DenseMatrix<MT2, false>&) [with MT1 = blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >; MT2 = blaze::DMatTransExpr<blaze::StaticMatrix<double, 9, 8, true>, false>]’
/home/kotlyar/software/blaze/blaze/math/expressions/TDMatTDMatMultExpr.h:4656:44:   required from ‘blaze::EnableIf_t<CanExploitSymmetry_v<MT, MT1, MT2> > blaze::smpAddAssign(blaze::Matrix<MT, false>&, const blaze::TDMatTDMatMultExpr< <template-parameter-1-1>, <template-parameter-1-2>, <anonymous>, <anonymous>, <anonymous>, <anonymous> >&) [with MT = blaze::Submatrix<blaze::DynamicMatrix<double, false>, blaze::unaligned, false, true, 0, 13, 9, 8>; MT1 = blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >; MT2 = blaze::StaticMatrix<double, 9, 8, true>; bool SF = false; bool HF = false; bool LF = false; bool UF = false; blaze::EnableIf_t<CanExploitSymmetry_v<MT, MT1, MT2> > = void]’
/home/kotlyar/software/blaze/blaze/math/views/submatrix/Dense.h:1499:19:   required from ‘blaze::DisableIf_t<EnforceEvaluation_v<MT, MT2>, blaze::Submatrix<MT, blaze::unaligned, false, true, CSAs ...>&> blaze::Submatrix<MT, blaze::unaligned, false, true, CSAs ...>::operator+=(const blaze::Matrix<MT, SO>&) [with MT2 = blaze::TDMatTDMatMultExpr<blaze::DiagonalMatrix<blaze::StaticMatrix<double, 9, 9, true> >, blaze::StaticMatrix<double, 9, 8, true>, false, false, false, false>; bool SO2 = true; MT = blaze::DynamicMatrix<double, false>; long unsigned int ...CSAs = {0, 13, 9, 8}; blaze::DisableIf_t<EnforceEvaluation_v<MT, MT2>, blaze::Submatrix<MT, blaze::unaligned, false, true, CSAs ...>&> = blaze::Submatrix<blaze::DynamicMatrix<double, false>, blaze::unaligned, false, true, 0, 13, 9, 8>&]’
test.cpp:18:40:   required from here
/home/kotlyar/software/blaze/blaze/math/constraints/MatMatMultExpr.h:105:43: error: static assertion failed: Invalid matrix/matrix multiplication expression detected
  104 |    static_assert( ::blaze::IsMatrix_v<T1> && \
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  105 |                   ::blaze::IsMatrix_v<T2> && \
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~^~~~
  106 |                   ( ( ::blaze::Size_v<T1,1UL> == -1L ) || \
      |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  107 |                     ( ::blaze::Size_v<T2,0UL> == -1L ) || \
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  108 |                     ( ::blaze::Size_v<T1,1UL> == ::blaze::Size_v<T2,0UL> ) ) \
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/kotlyar/software/blaze/blaze/math/expressions/TDMatDMatMultExpr.h:7253:4: note: in expansion of macro ‘BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR’
 7253 |    BLAZE_CONSTRAINT_MUST_FORM_VALID_MATMATMULTEXPR( MT1, MT2 );
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Changing the storage order of J to columnMajor makes the code compile. However, the code is expected to compile for every combination of storage orders.

Comments (5)

  1. Klaus Iglberger

    Hi Misha!

    Thanks a lot for creating an issue for this defect. You are correct, in this special case Blaze incorrectly reports an invalid matrix multiplication. We’ll fix the problem as quickly as possible. Thanks again,

    Best regards,

    Klaus!

  2. Klaus Iglberger

    Commit 1d30be3 resolves the compilation errors for the combination of a non-square static matrix and a diagonal static matrix in a dense matrix multiplication. The fix is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.8.

  3. Log in to comment