From 1b1b7e347d8c3566c89cd8510a52cde79dcc048b Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen <4643818-rmlarsen1@users.noreply.gitlab.com> Date: Thu, 26 Feb 2026 07:54:27 -0800 Subject: [PATCH] Fix EIGEN_NO_AUTOMATIC_RESIZING not resizing empty destinations libeigen/eigen!2219 Co-authored-by: Rasmus Munk Larsen --- Eigen/src/Core/AssignEvaluator.h | 3 + Eigen/src/Core/PlainObjectBase.h | 1 + test/CMakeLists.txt | 1 + test/evaluators.cpp | 1 + test/no_automatic_resizing.cpp | 106 +++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+) create mode 100644 test/no_automatic_resizing.cpp diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h index 3afdd3e62..abaa429ed 100644 --- a/Eigen/src/Core/AssignEvaluator.h +++ b/Eigen/src/Core/AssignEvaluator.h @@ -810,6 +810,9 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize_if_allowed(DstXprTyp (dst.size() == 0 || (DstXprType::IsVectorAtCompileTime ? (dst.size() == src.size()) : (dst.rows() == dstRows && dst.cols() == dstCols))) && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); + if (dst.size() == 0) { + dst.resize(dstRows, dstCols); + } #else dst.resize(dstRows, dstCols); eigen_assert(dst.rows() == dstRows && dst.cols() == dstCols); diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h index 1544a5821..2f4c357c5 100644 --- a/Eigen/src/Core/PlainObjectBase.h +++ b/Eigen/src/Core/PlainObjectBase.h @@ -685,6 +685,7 @@ class PlainObjectBase : public internal::dense_xpr_base::type { eigen_assert((this->size() == 0 || (IsVectorAtCompileTime ? (this->size() == other.size()) : (rows() == other.rows() && cols() == other.cols()))) && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); + if (this->size() == 0) resizeLike(other); EIGEN_ONLY_USED_FOR_DEBUG(other); #else resizeLike(other); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 916ac21ec..a70c1fc4c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -217,6 +217,7 @@ ei_add_test(indexed_view) ei_add_test(reshape) ei_add_test(swap) ei_add_test(resize) +ei_add_test(no_automatic_resizing) ei_add_test(conservative_resize) ei_add_test(product_small) ei_add_test(product_large) diff --git a/test/evaluators.cpp b/test/evaluators.cpp index 5a4ab3764..2941536f6 100644 --- a/test/evaluators.cpp +++ b/test/evaluators.cpp @@ -33,6 +33,7 @@ EIGEN_STRONG_INLINE DstXprType& copy_using_evaluator(const PlainObjectBase +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Test that EIGEN_NO_AUTOMATIC_RESIZING still allows assignment to +// default-constructed (empty) matrices and arrays. + +#define EIGEN_NO_AUTOMATIC_RESIZING +#include "main.h" + +template +void testNoAutomaticResizing() { + using Matrix = Eigen::Matrix; + using Vector = Eigen::Matrix; + using RowVector = Eigen::Matrix; + using Array = Eigen::Array; + using ArrayVector = Eigen::Array; + + const Index rows = internal::random(1, 50); + const Index cols = internal::random(1, 50); + + // Assignment of Zero expression to default-constructed matrix. + { + Matrix M; + M = Matrix::Zero(rows, cols); + VERIFY_IS_EQUAL(M.rows(), rows); + VERIFY_IS_EQUAL(M.cols(), cols); + VERIFY_IS_EQUAL(M.norm(), Scalar(0)); + } + + // Assignment of Zero expression to default-constructed array. + { + Array A; + A = Array::Zero(rows, cols); + VERIFY_IS_EQUAL(A.rows(), rows); + VERIFY_IS_EQUAL(A.cols(), cols); + } + + // Assignment of Ones expression to default-constructed matrix. + { + Matrix M; + M = Matrix::Ones(rows, cols); + VERIFY_IS_EQUAL(M.rows(), rows); + VERIFY_IS_EQUAL(M.cols(), cols); + } + + // Assignment of Random expression to default-constructed matrix. + { + Matrix M; + M = Matrix::Random(rows, cols); + VERIFY_IS_EQUAL(M.rows(), rows); + VERIFY_IS_EQUAL(M.cols(), cols); + } + + // Assignment from another matrix to default-constructed matrix. + { + Matrix src = Matrix::Random(rows, cols); + Matrix dst; + dst = src; + VERIFY_IS_EQUAL(dst.rows(), rows); + VERIFY_IS_EQUAL(dst.cols(), cols); + VERIFY_IS_APPROX(dst, src); + } + + // Vector assignment to default-constructed vector. + { + Vector v; + v = Vector::Zero(rows); + VERIFY_IS_EQUAL(v.size(), rows); + } + + // RowVector assignment to default-constructed row vector. + { + RowVector v; + v = RowVector::Zero(cols); + VERIFY_IS_EQUAL(v.size(), cols); + } + + // Array vector assignment to default-constructed array vector. + { + ArrayVector v; + v = ArrayVector::Zero(rows); + VERIFY_IS_EQUAL(v.size(), rows); + } + + // Column access after Zero initialization (reproducer for reported bug). + { + Array A; + A = Array::Zero(rows, cols); + for (Index j = 0; j < cols; ++j) { + auto c = A.col(j); + VERIFY_IS_EQUAL(c.rows(), rows); + } + } +} + +EIGEN_DECLARE_TEST(no_automatic_resizing) { + CALL_SUBTEST_1(testNoAutomaticResizing()); + CALL_SUBTEST_2(testNoAutomaticResizing()); + CALL_SUBTEST_3(testNoAutomaticResizing>()); +}