CI: Run the SVE build and test stages on one image and one compiler libeigen/eigen!2963 Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
diff --git a/.agents/ci.md b/.agents/ci.md index ea6dfb4..0c7fd7c 100644 --- a/.agents/ci.md +++ b/.agents/ci.md
@@ -169,7 +169,7 @@ compile coverage rather than a selection because its per-SVL test jobs already filter to a curated target subset through `EIGEN_CI_CTEST_REGEX`, which a selection would fight with. -SVE runs the selection, at two vector lengths rather than one. The backend is fixed-length — `EIGEN_ARM64_SVE_VL` +SVE runs the selection, at three vector lengths rather than one. The backend is fixed-length — `EIGEN_ARM64_SVE_VL` comes from `__ARM_FEATURE_SVE_BITS`, which only `-msve-vector-bits` sets — so each width is a separate build, and the packet code's fold counts and transpose networks differ between them. `test/sve_vector_length` guards the rest by reading `RDVL` and comparing it against the width the packets were built for, because a binary run at the wrong length
diff --git a/ci/build.linux.gitlab-ci.yml b/ci/build.linux.gitlab-ci.yml index 3c8ea48..28c1032 100644 --- a/ci/build.linux.gitlab-ci.yml +++ b/ci/build.linux.gitlab-ci.yml
@@ -598,27 +598,19 @@ -DEIGEN_TEST_CUSTOM_CXX_FLAGS=-march=armv8.2-a+sve -DCMAKE_CROSSCOMPILING_EMULATOR=qemu-aarch64;-L;/usr/aarch64-linux-gnu -# gcc-14 builds 128 bits and nothing wider. At -O3 with -msve-vector-bits=256 or -# above, gcc-14.2 miscompiles: redux_commutative<double> in test/redux.cpp sums -# a 16x16 block of a 17x17 matrix to 660 instead of 1022, deterministically. -# That is a compiler bug and not an Eigen one -- it reproduces with -# EIGEN_ARM64_USE_SVE unset, with GCC autovectorizing to fixed-length SVE while -# Eigen is on NEON -- and not an emulation artifact, since QEMU 8.2 and 10.0 -# produce the same wrong value. It goes away at -O2, with -# -fno-tree-slp-vectorize, and at 128 bits. -.build:linux:cross:sve:gcc-14: - extends: .build:linux:cross:sve - variables: - EIGEN_CI_CROSS_INSTALL: g++-14-aarch64-linux-gnu - EIGEN_CI_C_COMPILER: gcc-14 - EIGEN_CI_CXX_COMPILER: g++-14 - EIGEN_CI_CROSS_C_COMPILER: aarch64-linux-gnu-gcc-14 - EIGEN_CI_CROSS_CXX_COMPILER: aarch64-linux-gnu-g++-14 - -# Every width above 128, for the reason above: gcc-13.3 is clean at 128, 256 and -# 512. SVE ACLE needs only gcc-10, so nothing here depends on 14 the way SME's -# ACLE does. Revisit once the image carries a fixed gcc-14 or a gcc-15 aarch64 -# cross. +# One compiler for all three widths. gcc-14 is not usable above 128 bits: at -O3 +# with -msve-vector-bits=256 or above, gcc-14.2 miscompiles +# redux_commutative<double> in test/redux.cpp, summing a 16x16 block of a 17x17 +# matrix to 660 instead of 1022, deterministically. That is a compiler bug and +# not an Eigen one -- it reproduces with EIGEN_ARM64_USE_SVE unset, with GCC +# autovectorizing to fixed-length SVE while Eigen is on NEON -- and not an +# emulation artifact, since QEMU 8.2 and 10.0 produce the same wrong value. It +# goes away at -O2, with -fno-tree-slp-vectorize, and at 128 bits. +# +# gcc-13.3 is clean at 128, 256 and 512, and SVE ACLE needs only gcc-10, so +# nothing here depends on 14 the way SME's ACLE does. Naming one compiler is +# what lets the test jobs install the compiler their artifacts were built with, +# which the failtest and buildsystem tests require -- see .test:linux:sve. .build:linux:cross:sve:gcc-13: extends: .build:linux:cross:sve variables: @@ -634,8 +626,8 @@ # architecturally legal but unimplemented, and compile-only coverage of them # bought two latent compile fixes at the cost of running nothing -- if a wider # part ships, add it here with a test job rather than as a build on its own. -build:linux:cross:sve:gcc-14:vl128: - extends: .build:linux:cross:sve:gcc-14 +build:linux:cross:sve:gcc-13:vl128: + extends: .build:linux:cross:sve:gcc-13 variables: EIGEN_CI_ADDITIONAL_ARGS: >- -DEIGEN_TEST_SVE=ON @@ -673,7 +665,7 @@ EIGEN_CI_INSTALL: clang-14 EIGEN_CI_C_COMPILER: clang-14 EIGEN_CI_CXX_COMPILER: clang++-14 - EIGEN_CI_CROSS_INSTALL: g++-14-aarch64-linux-gnu clang-14 + EIGEN_CI_CROSS_INSTALL: g++-13-aarch64-linux-gnu clang-14 EIGEN_CI_ADDITIONAL_ARGS: >- -DEIGEN_TEST_SVE=ON -DEIGEN_TEST_SVE_VL=128 @@ -959,10 +951,10 @@ # The VL sweep is the point of the affected tier for SVE: a change to the packet # code is exactly what breaks at one vector length and not another. -build:linux:cross:sve:gcc-14:vl128:affected: - extends: build:linux:cross:sve:gcc-14:vl128 +build:linux:cross:sve:gcc-13:vl128:affected: + extends: build:linux:cross:sve:gcc-13:vl128 variables: - EIGEN_CI_CCACHE_POOL: build-linux-cross-sve-gcc-14-vl128 + EIGEN_CI_CCACHE_POOL: build-linux-cross-sve-gcc-13-vl128 rules: !reference [.rules:libeigen:affected-tests:sve, rules] build:linux:cross:sve:gcc-13:vl512:affected:
diff --git a/ci/test.linux.gitlab-ci.yml b/ci/test.linux.gitlab-ci.yml index b93edc4..8a86c23 100644 --- a/ci/test.linux.gitlab-ci.yml +++ b/ci/test.linux.gitlab-ci.yml
@@ -556,9 +556,14 @@ # jobs are NEON and the SME jobs above take the NEON headers. .test:linux:sve: extends: .test:linux - # qemu >= 10 for the sve-default-vector-length property used below; Ubuntu - # 24.04 ships 8.2. Same split as the SME jobs: build on 24.04, test on 26.04. - image: ubuntu:26.04 + # No image override: these run on the same ubuntu:24.04 the SVE builds use. + # An earlier split put the test stage on 26.04 for "qemu >= 10 for the + # sve-default-vector-length property", but 24.04's qemu-user 8.2.2 honours + # that property at every width -- measured with an RDVL probe at 128, 256, + # 512, 1024 and 2048, and by sve_vector_length itself, which fails if the + # emulated width ever disagrees with EIGEN_ARM64_SVE_VL. The SME jobs keep + # their own 26.04 split: theirs is FEAT_SME2 multi-vector emulation, which + # 8.2 genuinely lacks, and is unrelated to this property. variables: EIGEN_CI_TARGET_ARCH: aarch64-sve EIGEN_CI_CROSS_TARGET_TRIPLE: aarch64-linux-gnu @@ -574,12 +579,19 @@ # too; the :official jobs are unaffected either way, as both names are # Unsupported tests. EIGEN_CI_CTEST_EXCLUDE: tensor_thread_pool|FFT - # The test stage never compiles, so no build compiler is named here and one - # anchor serves both widths whichever GCC built them: all this needs is the - # aarch64 runtime and qemu-user, and the default-version cross g++ supplies - # the libraries on any release. - EIGEN_CI_CXX_COMPILER: aarch64-linux-gnu-g++ - EIGEN_CI_CROSS_INSTALL: g++-aarch64-linux-gnu qemu-user + # Name the compiler the artifacts were built with, not the default-version + # cross g++. The test stage does compile: the failtest targets are + # EXCLUDE_FROM_ALL and their ctest command is `cmake --build`, and the + # buildsystem scenarios configure nested projects with the parent cache's + # CMAKE_CXX_COMPILER baked in (test/buildsystem/CMakeLists.txt). Both read + # the absolute path CMake resolved at configure time, so an image without + # that exact binary fails them -- 62 failtests and 9 buildsystem tests at + # once, and the failtest _ko halves then pass vacuously, WILL_FAIL being + # unable to tell the asserted compile error from a missing compiler. Only + # the affected tier saw this: the :official and :unsupported jobs filter by + # label, and neither family carries the labels they select. + EIGEN_CI_CXX_COMPILER: aarch64-linux-gnu-g++-13 + EIGEN_CI_CROSS_INSTALL: g++-13-aarch64-linux-gnu qemu-user # Each concrete job must set QEMU_CPU, and both halves of it: sveN=on advertises # the width, sve-default-vector-length (in bytes) selects the one a task @@ -589,7 +601,7 @@ # EIGEN_ARM64_SVE_VL and fails if this is ever wrong. .test:linux:sve:vl128: extends: .test:linux:sve - needs: [ build:linux:cross:sve:gcc-14:vl128 ] + needs: [ build:linux:cross:sve:gcc-13:vl128 ] variables: QEMU_CPU: max,sve128=on,sve-default-vector-length=16 @@ -611,14 +623,14 @@ # (four- and eight-wide double packets, deeper predux_mul folds and ptranspose # networks), and a packet size of eight, which is where the GEBP column-group # guard went wrong, is reached by float at 256 and by double at 512. The job -# names carry the compiler that built the binaries, which is gcc-13 above 128 -# bits -- see the note on .build:linux:cross:sve:gcc-14. -test:linux:sve128:gcc-14:official: +# names carry the compiler that built the binaries, which is gcc-13 at every +# width -- see the note on .build:linux:cross:sve:gcc-13. +test:linux:sve128:gcc-13:official: extends: .test:linux:sve:vl128 variables: EIGEN_CI_CTEST_LABEL: Official -test:linux:sve128:gcc-14:unsupported: +test:linux:sve128:gcc-13:unsupported: extends: .test:linux:sve:vl128 variables: EIGEN_CI_CTEST_LABEL: Unsupported @@ -999,9 +1011,9 @@ # Three vector lengths: the SVE packet code has VL-dependent fold counts and # transpose networks, so a single length is not a meaningful affected-tier # signal for a change under arch/SVE. -test:linux:sve128:gcc-14:affected: +test:linux:sve128:gcc-13:affected: extends: [ .test:linux:sve:vl128, .affected:test ] - needs: [ build:linux:cross:sve:gcc-14:vl128:affected, select:tests ] + needs: [ build:linux:cross:sve:gcc-13:vl128:affected, select:tests ] rules: !reference [.rules:libeigen:affected-tests:sve, rules] test:linux:sve256:gcc-13:affected: