Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of Eigen causes segmentation faults in digitization reader #4049

Open
stephenswat opened this issue Jan 25, 2025 · 3 comments · May be fixed by #4098
Open

Use of Eigen causes segmentation faults in digitization reader #4049

stephenswat opened this issue Jan 25, 2025 · 3 comments · May be fixed by #4098

Comments

@stephenswat
Copy link
Member

When using an installed version of ACTS with the JSON libraries, i.e. compiled and installed to the filesystem and then loaded via find_package, I am observing a segmentation fault related to the use of an Eigen matrix in the reading of the digitization configuration:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6117935 in _mm512_store_pd (__P=0x7fffffff9d20, __A=...) at /usr/lib/gcc/x86_64-linux-gnu/14/include/avx512fintrin.h:4192
4192      *(__m512d *) __P = __A;

The backtrace looks as follows:

#0  0x00007ffff6117935 in _mm512_store_pd (__P=0x7fffffff9d20, __A=...) at /usr/lib/gcc/x86_64-linux-gnu/14/include/avx512fintrin.h:4192
#1  Eigen::internal::pstore<double, double __vector(8)>(double*, double __vector(8) const&) (to=0x7fffffff9d20, from=...)
    at /storage/spack/linux-debiann-zen4/gcc-14.2.0/eigen-3.4.0-v7737qx6pcvxcoqnu34kmp3ejljs755e/include/eigen3/Eigen/src/Core/arch/AVX512/PacketMath.h:775
#2  0x00007ffff612caa5 in Eigen::internal::pstoret<double, double __vector(8), 64>(double*, double __vector(8) const&) (to=0x7fffffff9d20, from=...)
    at /storage/spack/linux-debiann-zen4/gcc-14.2.0/eigen-3.4.0-v7737qx6pcvxcoqnu34kmp3ejljs755e/include/eigen3/Eigen/src/Core/GenericPacketMath.h:978
#3  Eigen::internal::assign_op<double, double>::assignPacket<64, double __vector(8)>(double*, double __vector(8) const&) const (this=0x7fffffff923f, a=0x7fffffff9d20, b=...)
    at /storage/spack/linux-debiann-zen4/gcc-14.2.0/eigen-3.4.0-v7737qx6pcvxcoqnu34kmp3ejljs755e/include/eigen3/Eigen/src/Core/functors/AssignmentFunctors.h:28
[some frames skipped for brevity]
#13 0x00007ffff616f3a1 in Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 4, 0, 4, 4> >::_set<Eigen::Matrix<double, 4, 4, 0, 4, 4> > (this=0x7fffffff9d20, other=...)
    at /storage/spack/linux-debiann-zen4/gcc-14.2.0/eigen-3.4.0-v7737qx6pcvxcoqnu34kmp3ejljs755e/include/eigen3/Eigen/src/Core/PlainObjectBase.h:779
#14 0x00007ffff616d4dd in Eigen::Matrix<double, 4, 4, 0, 4, 4>::operator= (this=0x7fffffff9d20, other=...)
    at /storage/spack/linux-debiann-zen4/gcc-14.2.0/eigen-3.4.0-v7737qx6pcvxcoqnu34kmp3ejljs755e/include/eigen3/Eigen/src/Core/Matrix.h:208
#15 0x00007ffff616bbcd in Eigen::Transform<double, 3, 2, 0>::operator= (this=0x7fffffff9d20)
    at /storage/spack/linux-debiann-zen4/gcc-14.2.0/eigen-3.4.0-v7737qx6pcvxcoqnu34kmp3ejljs755e/include/eigen3/Eigen/src/Geometry/Transform.h:204
#16 0x00007ffff62ef93b in Acts::BinUtility::operator+= (this=0x7fffffff9ce0, gbu=...)
    at /storage/spack-stage/stephen/spack-stage-acts-38.2.0-poec35rcqi63nupd6il6kzueljoua3nb/spack-src/Core/include/Acts/Utilities/BinUtility.hpp:123
#17 0x00007ffff31dfccb in Acts::from_json (j=..., bu=...)
    at /storage/spack-stage/stephen/spack-stage-acts-38.2.0-poec35rcqi63nupd6il6kzueljoua3nb/spack-src/Plugins/Json/src/UtilitiesJsonConverter.cpp:102
#18 0x00007ffff7c46fef in traccc::from_json (json=..., cfg=...) at /home/stephen/Projects/traccc/io/src/json/read_digitization_config.cpp:38
#19 0x00007ffff7c4e501 in nlohmann::json_abi_v3_11_3::detail::from_json_fn::operator()<nlohmann::json_abi_v3_11_3::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> >, void>, traccc::module_digitization_config&> (
    this=0x7ffff7c95aea <nlohmann::json_abi_v3_11_3::detail::static_const<nlohmann::json_abi_v3_11_3::detail::from_json_fn>::value>, j=..., val=...)
    at /home/stephen/.spack_install/var/spack/environments/traccc/.spack-env/view/include/nlohmann/detail/conversions/from_json.hpp:478
#20 0x00007ffff7c4c044 in nlohmann::json_abi_v3_11_3::adl_serializer<traccc::module_digitization_config, void>::from_json<nlohmann::json_abi_v3_11_3::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> >, void> const&, traccc::module_digitization_config> (j=..., val=...)
    at /home/stephen/.spack_install/var/spack/environments/traccc/.spack-env/view/include/nlohmann/adl_serializer.hpp:31
#21 0x00007ffff7c4bf99 in nlohmann::json_abi_v3_11_3::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> >, void>::get_impl<traccc::module_digitization_config, 0> (this=0x5555555f6390) at /home/stephen/.spack_install/var/spack/environments/traccc/.spack-env/view/include/nlohmann/json.hpp:1610
#22 0x00007ffff7c49e50 in nlohmann::json_abi_v3_11_3::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> >, void>::get<traccc::module_digitization_config, traccc::module_digitization_config> (this=0x5555555f6390)
    at /home/stephen/.spack_install/var/spack/environments/traccc/.spack-env/view/include/nlohmann/json.hpp:1753
#23 0x00007ffff7c48dd7 in Acts::GeometryHierarchyMapJsonConverter<traccc::module_digitization_config, void>::fromJson (
    this=0x7ffff7d75668 <traccc::io::json::read_digitization_config(std::basic_string_view<char, std::char_traits<char> >)::converter>, encoded=...)
    at /home/stephen/.spack_install/var/spack/environments/traccc/.spack-env/view/include/Acts/Plugins/Json/GeometryHierarchyMapJsonConverter.hpp:193
#24 0x00007ffff7c47253 in traccc::io::json::read_digitization_config (filename=...) at /home/stephen/Projects/traccc/io/src/json/read_digitization_config.cpp:67

This suggests to me that we are somehow configuring Eigen in a specific way when compiling the digitization code and then slightly differently downstream; for example because some compiler flag might not be properly propagated outwards.

Has anyone encountered such issues before?

@paulgessinger
Copy link
Member

Are we sure it's the same Eigen version?

@stephenswat
Copy link
Member Author

Are we sure it's the same Eigen version?

Yes, I've quadruple tested this.

Writing down some findings for posterity.

#0  0x00007ffff662109e in _mm512_store_pd (__P=0x7fffffff86e0, __A=...) at /usr/lib/gcc/x86_64-linux-gnu/14/include/avx512fintrin.h:4192
#1  Eigen::internal::pstore<double, double __vector(8)>(double*, double __vector(8) const&) (to=0x7fffffff86e0, from=...)

It is clear that we are tying to store one AVX-512 register (of width 512 bits, i.e. 64 bytes) to 0x7fffffff86e0. This store requires the operand to be 64-byte aligned, but clearly it is not; 0x7fffffff86e0 is aligned only to 32 byte boundaries. But this problem is not caused by the matrix itself being wrongly aligned. Indeed:

(gdb) p &cfg.segmentation.m_transform
$36 = (Acts::Transform3 *) 0x7fffffff86c0

So we know that this transform starts exactly 32 bytes (4 doubles) before the invalid access, and this matrix is perfectly well aligned to 64 bytes.

So Eigen is, for whatever reason, trying to insert a 64-byte-alignent-requiring store on a 64-byte-aligned matrix, but it is issuing it 32 bytes after the beginning of the matrix, thereby destroying the alignment.

stephenswat added a commit to stephenswat/acts that referenced this issue Feb 18, 2025
As I discovered in acts-project#4049, having Eigen3 types on ABI boundaries invites
a variety of compiler issues. In cases where ACTS and the depending
project are compiled with different vectorization instruction sets, the
ABIs become incompatible with each other, because the matrices are
differently aligned.

This commit adds the `ACTS_ENFORCE_EIGEN3_ALIGNMENT` flag which, if
enabled, will encode the Eigen3 alignment in the ACTS shared object, and
the ACTS `find_package` code will then attempt to read this and set it
appropriately on any dependent targets.

Closes acts-project#4049.
@stephenswat stephenswat linked a pull request Feb 18, 2025 that will close this issue
stephenswat added a commit to stephenswat/acts that referenced this issue Feb 18, 2025
As I discovered in acts-project#4049, having Eigen3 types on ABI boundaries invites
a variety of compiler issues. In cases where ACTS and the depending
project are compiled with different vectorization instruction sets, the
ABIs become incompatible with each other, because the matrices are
differently aligned.

This commit adds the `ACTS_ENFORCE_EIGEN3_ALIGNMENT` flag which, if
enabled, will encode the Eigen3 alignment in the ACTS shared object, and
the ACTS `find_package` code will then attempt to read this and set it
appropriately on any dependent targets.

Closes acts-project#4049.
stephenswat added a commit to stephenswat/acts that referenced this issue Feb 18, 2025
As I discovered in acts-project#4049, having Eigen3 types on ABI boundaries invites
a variety of compiler issues. In cases where ACTS and the depending
project are compiled with different vectorization instruction sets, the
ABIs become incompatible with each other, because the matrices are
differently aligned.

This commit adds the `ACTS_ENFORCE_EIGEN3_ALIGNMENT` flag which, if
enabled, will encode the Eigen3 alignment in the ACTS shared object, and
the ACTS `find_package` code will then attempt to read this and set it
appropriately on any dependent targets.

Closes acts-project#4049.
stephenswat added a commit to stephenswat/acts that referenced this issue Feb 18, 2025
As I discovered in acts-project#4049, having Eigen3 types on ABI boundaries invites
a variety of compiler issues. In cases where ACTS and the depending
project are compiled with different vectorization instruction sets, the
ABIs become incompatible with each other, because the matrices are
differently aligned.

This commit adds the `ACTS_ENFORCE_EIGEN3_ALIGNMENT` flag which, if
enabled, will encode the Eigen3 alignment in the ACTS shared object, and
the ACTS `find_package` code will then attempt to read this and set it
appropriately on any dependent targets.

Closes acts-project#4049.
@paulgessinger
Copy link
Member

test comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants