Merge remote-tracking branch 'origin2/master'

This commit is contained in:
Chip Kerchner
2025-10-28 20:26:26 +00:00
16 changed files with 103 additions and 66 deletions

View File

@@ -15,6 +15,7 @@
#include "Householder"
#include "LU"
#include "Geometry"
#include "Sparse" // Needed by ComplexQZ.
#include "src/Core/util/DisableStupidWarnings.h"

View File

@@ -2831,7 +2831,7 @@ inline __m128i segment_mask_4x8(Index begin, Index count) {
mask <<= CHAR_BIT * count;
mask--;
mask <<= CHAR_BIT * begin;
#if defined(_WIN32) && !defined(_WIN64)
#if !EIGEN_ARCH_x86_64
return _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&mask));
#else
return _mm_cvtsi64_si128(mask);
@@ -2847,7 +2847,7 @@ inline __m128i segment_mask_8x8(Index begin, Index count) {
mask <<= (CHAR_BIT / 2) * count;
mask--;
mask <<= CHAR_BIT * begin;
#if defined(_WIN32) && !defined(_WIN64)
#if !EIGEN_ARCH_x86_64
return _mm_loadl_epi64(reinterpret_cast<const __m128i*>(&mask));
#else
return _mm_cvtsi64_si128(mask);

View File

@@ -14,8 +14,6 @@
#ifndef EIGEN_COMPLEX_QZ_H_
#define EIGEN_COMPLEX_QZ_H_
#include "../../Sparse"
// IWYU pragma: private
#include "./InternalHeaderCheck.h"
@@ -126,9 +124,7 @@ class ComplexQZ {
computeQZ ? n : (MatrixType::ColsAtCompileTime == Eigen::Dynamic ? 0 : MatrixType::ColsAtCompileTime)),
m_ws(2 * n),
m_computeQZ(computeQZ),
m_maxIters(maxIters){
};
m_maxIters(maxIters) {}
/** \brief Constructor. computes the QZ decomposition of given matrices
* upon creation
@@ -178,14 +174,14 @@ class ComplexQZ {
*
* \returns \c Success if computation was successfull, \c NoConvergence otherwise.
*/
ComputationInfo info() const { return m_info; };
ComputationInfo info() const { return m_info; }
/** \brief number of performed QZ steps
*/
unsigned int iterations() const {
eigen_assert(m_isInitialized && "ComplexQZ is not initialized.");
return m_global_iter;
};
}
private:
Index m_n;
@@ -569,7 +565,9 @@ void ComplexQZ<MatrixType_>::push_down_zero_ST(Index k, Index l) {
for (Index j = k + 1; j <= l; j++) {
// Create a 0 at _T(j, j)
J.makeGivens(m_T(j - 1, j), m_T(j, j), &m_T.coeffRef(j - 1, j));
m_T.rightCols(m_n - j - 1).applyOnTheLeft(j - 1, j, J.adjoint());
if (m_n - j - 1 > 0) {
m_T.rightCols(m_n - j - 1).applyOnTheLeft(j - 1, j, J.adjoint());
}
m_T.coeffRef(j, j) = Scalar(0);
m_S.applyOnTheLeft(j - 1, j, J.adjoint());

View File

@@ -65,7 +65,6 @@ template <typename EssentialPart>
EIGEN_DEVICE_FUNC void MatrixBase<Derived>::makeHouseholder(EssentialPart& essential, Scalar& tau,
RealScalar& beta) const {
using numext::conj;
using numext::sqrt;
EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size() - 1);
@@ -79,7 +78,7 @@ EIGEN_DEVICE_FUNC void MatrixBase<Derived>::makeHouseholder(EssentialPart& essen
beta = numext::real(c0);
essential.setZero();
} else {
beta = sqrt(numext::abs2(c0) + tailSqNorm);
beta = numext::sqrt(numext::abs2(c0) + tailSqNorm);
if (numext::real(c0) >= RealScalar(0)) beta = -beta;
essential = tail / (c0 - beta);
tau = conj((beta - c0) / beta);

View File

@@ -89,7 +89,7 @@ struct simpl_chol_helper {
m_set[u] = v;
u = next;
}
};
}
};
// Computes the higher adjacency pattern by transposing the input lower adjacency matrix.

View File

@@ -140,7 +140,7 @@ class SparseVector : public SparseCompressedBase<SparseVector<Scalar_, Options_,
return insertBack(inner);
}
inline Scalar& insertBack(Index i) {
m_data.append(0, i);
m_data.append(Scalar(0), i);
return m_data.value(m_data.size() - 1);
}
@@ -150,7 +150,7 @@ class SparseVector : public SparseCompressedBase<SparseVector<Scalar_, Options_,
return insertBackUnordered(inner);
}
inline Scalar& insertBackUnordered(Index i) {
m_data.append(0, i);
m_data.append(Scalar(0), i);
return m_data.value(m_data.size() - 1);
}
@@ -177,7 +177,7 @@ class SparseVector : public SparseCompressedBase<SparseVector<Scalar_, Options_,
--p;
}
m_data.index(p + 1) = convert_index(i);
m_data.value(p + 1) = 0;
m_data.value(p + 1) = Scalar(0);
return m_data.value(p + 1);
}
@@ -367,7 +367,7 @@ class SparseVector : public SparseCompressedBase<SparseVector<Scalar_, Options_,
/** \internal \deprecated use insertBack(Index) */
EIGEN_DEPRECATED_WITH_REASON("Use .insertBack() instead.") Scalar& fill(Index i) {
m_data.append(0, i);
m_data.append(Scalar(0), i);
return m_data.value(m_data.size() - 1);
}

View File

@@ -290,7 +290,7 @@ build:linux:cross:x86-64:gcc-10:default:smoketest:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
tags:
- saas-linux-small-amd64
- saas-linux-medium-amd64
build:linux:cross:x86-64:clang-12:default:smoketest:
extends: build:linux:cross:x86-64:clang-12:default
@@ -299,4 +299,4 @@ build:linux:cross:x86-64:clang-12:default:smoketest:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
tags:
- saas-linux-small-amd64
- saas-linux-medium-amd64

View File

@@ -13,19 +13,29 @@ elif [[ ${EIGEN_CI_CTEST_LABEL} ]]; then
target="-L ${EIGEN_CI_CTEST_LABEL}"
fi
# Repeat tests up to three times to ignore flakes. Do not re-run with -T test,
# otherwise we lose test results for those that passed.
# Note: starting with CMake 3.17, we can use --repeat until-pass:3, but we have
# no way of easily installing this on ppc64le.
ctest ${EIGEN_CI_CTEST_ARGS} --parallel ${NPROC} \
--output-on-failure --no-compress-output \
--build-no-clean -T test ${target} || \
ctest ${EIGEN_CI_CTEST_ARGS} --parallel ${NPROC} \
--output-on-failure --no-compress-output --rerun-failed || \
ctest ${EIGEN_CI_CTEST_ARGS} --parallel ${NPROC} \
--output-on-failure --no-compress-output --rerun-failed
set +x
ctest_cmd="ctest ${EIGEN_CI_CTEST_ARGS} --parallel ${NPROC} --output-on-failure --no-compress-output --build-noclean ${target}"
echo "Running initial tests..."
if ${ctest_cmd} -T test; then
echo "Tests passed on the first attempt."
exit_code=$?
else
echo "Initial tests failed with exit code $?. Retrying up to ${EIGEN_CI_CTEST_REPEAT} times..."
if ${ctest_cmd} --rerun-failed --repeat until-pass:${EIGEN_CI_CTEST_REPEAT}; then
echo "Tests passed on retry."
exit_code=42
else
exit_code=$?
fi
fi
set -x
# Return to root directory.
cd ${rootdir}
set +x
exit $exit_code

View File

@@ -13,18 +13,32 @@ if (${EIGEN_CI_CTEST_REGEX}) {
$target = "-L","${EIGEN_CI_CTEST_LABEL}"
}
# Repeat tests up to three times to ignore flakes. Do not re-run with -T test,
# otherwise we lose test results for those that passed.
# Note: starting with CMake 3.17, we can use --repeat until-pass:3, but we have
# no way of easily installing this on ppc64le.
ctest $EIGEN_CI_CTEST_ARGS -j$NPROC --output-on-failure --no-compress-output --build-no-clean -T test $target || `
ctest $EIGEN_CI_CTEST_ARGS -j$NPROC --output-on-failure --no-compress-output --rerun-failed || `
ctest $EIGEN_CI_CTEST_ARGS -j$NPROC --output-on-failure --no-compress-output --rerun-failed
$ctest_cmd = { ctest ${EIGEN_CI_CTEST_ARGS} --parallel ${NPROC} --output-on-failure --no-compress-output --build-noclean ${target} }
$success = $LASTEXITCODE
Write-Host "Running initial tests..."
& $ctest_cmd "-T test"
$exit_code = $LASTEXITCODE
if ($exit_code -eq 0) {
Write-Host "Tests passed on the first attempt."
}
else {
Write-Host "Initial tests failed with exit code $exit_code. Retrying up to $EIGEN_CI_CTEST_REPEAT times..."
# TODO: figure out how to use --repeat until-pass
for ($i = 1; $i -le $EIGEN_CI_CTEST_REPEAT; $i++) {
& $ctest_cmd "--rerun-failed"
$exit_code = $LASTEXITCODE
if ($exit_code -eq 0) {
Write-Host "Tests passed on retry."
$exit_code = 42
break
}
}
}
# Return to root directory.
cd ${rootdir}
# Explicitly propagate exit code to indicate pass/failure of test command.
if($success -ne 0) { Exit $success }
Exit $exit_code

View File

@@ -11,6 +11,8 @@
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_PROJECT_NAMESPACE == "libeigen" && $CI_MERGE_REQUEST_LABELS =~ "/all-tests/"
tags:
- saas-linux-2xlarge-amd64
allow_failure:
exit_codes: 42
##### x86-64 ###################################################################
.test:linux:x86-64:
@@ -384,7 +386,7 @@ test:linux:x86-64:gcc-10:default:smoketest:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
tags:
- saas-linux-small-amd64
- saas-linux-medium-amd64
test:linux:x86-64:clang-12:default:smoketest:
extends: .test:linux:x86-64:clang-12:default
@@ -394,4 +396,4 @@ test:linux:x86-64:clang-12:default:smoketest:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
tags:
- saas-linux-small-amd64
- saas-linux-medium-amd64

View File

@@ -9,11 +9,12 @@
- if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "web" && $CI_PROJECT_NAMESPACE == "libeigen"
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_PROJECT_NAMESPACE == "libeigen" && $CI_MERGE_REQUEST_LABELS =~ "/all-tests/"
tags:
- eigen-runner
- windows
- x86-64
allow_failure:
exit_codes: 42
##### MSVC #####################################################################

View File

@@ -91,7 +91,7 @@ set(ei_smoke_test_list
qr_1
qr_colpivoting_7
qr_fullpivoting_4
rand
rand_1
real_qz_1
redux_1
ref_1

View File

@@ -36,9 +36,9 @@ option in `find_package`:
```
find_package(Eigen3 3.4 REQUIRED NO_MODULE) # Restricts to 3.4.z
```
or to support a range of versions:
Starting with Eigen 3.4.1, we also support a range spanning major versions:
```
find_package(Eigen3 3.4...5 REQUIRED NO_MODULE) # Any version >=3.4.0 but <6.0.0.
find_package(Eigen3 3.4...5 REQUIRED NO_MODULE) # Any version >=3.4.1 but <6.0.0.
```
Do not forget to set the <a href="https://cmake.org/cmake/help/v3.7/variable/CMAKE_PREFIX_PATH.html">\c CMAKE_PREFIX_PATH </a> variable if Eigen is not installed in a default location or if you want to pick a specific version. For instance:

View File

@@ -18,11 +18,9 @@
template <typename MatrixType>
void generate_random_matrix_pair(const Index dim, MatrixType& A, MatrixType& B) {
A.resize(dim, dim);
B.resize(dim, dim);
A.setRandom();
B.setRandom();
// Set each row of B with a probability of 10% to 0
A.setRandom(dim, dim);
B.setRandom(dim, dim);
// Zero out each row of B to with a probability of 10%.
for (int i = 0; i < dim; i++) {
if (internal::random<int>(0, 10) == 0) B.row(i).setZero();
}
@@ -59,8 +57,6 @@ void complex_qz(const MatrixType& A, const MatrixType& B) {
}
EIGEN_DECLARE_TEST(complex_qz) {
// const Index dim1 = 15;
// const Index dim2 = 80;
for (int i = 0; i < g_repeat; i++) {
// Check for very small, fixed-sized double- and float complex matrices
Eigen::Matrix2cd A_2x2, B_2x2;
@@ -71,16 +67,18 @@ EIGEN_DECLARE_TEST(complex_qz) {
A_3x3.setRandom();
B_3x3.setRandom();
B_3x3.col(i % 3).setRandom();
// Test for small float complex matrices
Eigen::MatrixXcf A_float, B_float;
const Index dim1 = internal::random<Index>(15, 80), dim2 = internal::random<Index>(15, 80);
generate_random_matrix_pair(dim1, A_float, B_float);
// Test for a bit larger double complex matrices
Eigen::MatrixXcd A_double, B_double;
generate_random_matrix_pair(dim2, A_double, B_double);
CALL_SUBTEST_1(complex_qz(A_2x2, B_2x2));
CALL_SUBTEST_2(complex_qz(A_3x3, B_3x3));
// Test for float complex matrices
const Index dim = internal::random<Index>(15, 80);
Eigen::MatrixXcf A_float, B_float;
generate_random_matrix_pair(dim, A_float, B_float);
CALL_SUBTEST_3(complex_qz(A_float, B_float));
// Test for double complex matrices
Eigen::MatrixXcd A_double, B_double;
generate_random_matrix_pair(dim, A_double, B_double);
CALL_SUBTEST_4(complex_qz(A_double, B_double));
}
}

View File

@@ -186,7 +186,7 @@ inline void on_temporary_creation(long int size, int) {
namespace Eigen {
static std::vector<std::string> g_test_stack;
// level == 0 <=> abort if test fail
// level == 0 <=> return 1 if test fail
// level >= 1 <=> warning message to std::cerr if test fail
static int g_test_level = 0;
static int g_repeat = 1;
@@ -356,7 +356,7 @@ inline void verify_impl(bool condition, const char* testname, const char* file,
const int test_stack_size = static_cast<int>(Eigen::g_test_stack.size());
for (int i = test_stack_size - 1; i >= 0; --i) std::cerr << " - " << Eigen::g_test_stack[i] << "\n";
std::cerr << "\n";
if (Eigen::g_test_level == 0) abort();
if (Eigen::g_test_level == 0) exit(1);
}
}
@@ -858,6 +858,12 @@ inline void set_seed_from_string(const char* str) {
g_has_set_seed = true;
}
inline void set_seed_from_time() {
using namespace std::chrono;
long long ns = duration_cast<nanoseconds>(high_resolution_clock::now().time_since_epoch()).count();
g_seed = static_cast<decltype(g_seed)>(ns);
}
int main(int argc, char* argv[]) {
g_has_set_repeat = false;
g_has_set_seed = false;
@@ -896,7 +902,7 @@ int main(int argc, char* argv[]) {
char* env_EIGEN_SEED = getenv("EIGEN_SEED");
if (!g_has_set_seed && env_EIGEN_SEED) set_seed_from_string(env_EIGEN_SEED);
if (!g_has_set_seed) g_seed = (unsigned int)time(NULL);
if (!g_has_set_seed) set_seed_from_time();
if (!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;
std::cout << "Initializing random number generator with seed " << g_seed << std::endl;

View File

@@ -454,8 +454,16 @@ ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixSolver, BisSPD>::compu
}
}
if (!(mode == 1 && isBempty) && !(mode == 2 && isBempty) && OP.info() != Success)
std::cout << "Error factoring matrix" << std::endl;
if (!(mode == 1 && isBempty) && !(mode == 2 && isBempty) && OP.info() != Success) {
m_info = OP.info() delete[] v;
delete[] iparam;
delete[] ipntr;
delete[] workd;
delete[] workl;
delete[] resid;
m_isInitialized = false;
return *this;
}
do {
internal::arpack_wrapper<Scalar, RealScalar>::saupd(&ido, bmat, &n, whch, &nev, &tol, resid, &ncv, v, &ldv, iparam,
@@ -572,7 +580,7 @@ ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixSolver, BisSPD>::compu
delete[] workl;
delete[] resid;
m_isInitialized = true;
m_isInitialized = (m_info == Success);
return *this;
}