HouseholderQR::_solve_impl, ColPivHouseholderQR::_solve_impl, and FullPivHouseholderQR::_solve_impl allocate memory when they shouldn't

Summary

HouseholderQR allocates memory in _solve_impl

Environment

  • Operating System : Windows/Linux
  • Architecture : x64
  • Eigen Version : 3.4.0
  • Compiler Version : MSVC v193, x86_64-linux-gnu-clang-18, x86_64-linux-gnu-gcc-14

Minimal Example

#define EIGEN_RUNTIME_NO_MALLOC
#include <Eigen/Core>

int main(int argc, char** argv) {
  using JJ_type = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
  
  JJ_type  JJ(3, 3);
  // fill JJ with some input data here
  Eigen::VectorXd b(3);
  // fill b with some data
  Eigen::VectorXd y(3);
  
  
  Eigen::HouseholderQR<JJ_type> qr(3, 3);
  // Now, all memory required should have been pre-allocated inside qr.
  
  Eigen::internal::set_is_malloc_allowed(false);
  qr.compute(JJ);
  y = qr.solve(b); // ALLOCATION HAPPENS HERE
  
}

Steps to reproduce

  1. create HouseholderQR with the constructor taking two Eigen::Indexes to preallocate memory.
  2. preallocate the vector to hold the result
  3. call qr.compute on some square matrix
  4. call y = qr.solve(b) for some vector b

What is the current bug behavior?

HouseholderQR::solve allocates memory

What is the expected correct behavior?

HouseholderQR::solve should not allocate memory

Anything else that might help

The allocation happens in HouseholderQR<_MatrixType>::_solve_impl in HouseholderQR.h.

template<typename _MatrixType>
template<typename RhsType, typename DstType>
void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
{
  const Index rank = (std::min)(rows(), cols());

  typename RhsType::PlainObject c(rhs); // ALLOCATION HERE!

  c.applyOnTheLeft(householderQ().setLength(rank).adjoint() );

  m_qr.topLeftCorner(rank, rank)
      .template triangularView<Upper>()
      .solveInPlace(c.topRows(rank));

  dst.topRows(rank) = c.topRows(rank);
  dst.bottomRows(cols()-rank).setZero();
}
  • Have a plan to fix this issue.