xtensor-stack / xtensor

C++ tensors with broadcasting and lazy computing
BSD 3-Clause "New" or "Revised" License
3.32k stars 394 forks source link

xtensor fails to build on mipsel architecture #2440

Open drew-parsons opened 2 years ago

drew-parsons commented 2 years ago

Build of xtensor 0.23.10 is failing on Linux (Debian experimental) on mipsel architecture. Building with g++ 10.3.0.

An undefined reference is declared at several points, to both umodsi3, and divsi3

One excerpt from the build log reports

[  3%] Linking CXX executable test_extended_xhistogram
cd /<<PKGBUILDDIR>>/obj-mipsel-linux-gnu/test && /usr/bin/cmake -E cmake_link_script CMakeFiles/test_extended_xhistogram.dir/link.txt --verbose=1
/usr/bin/c++ -O0 -march=native -std=c++14 -Wunused-parameter -Wextra -Wreorder -Wconversion -Wsign-conversion -Wold-style-cast -Wunused-variable -ftemplate-backtrace-limit=0 -Wl,-z,relro -rdynamic CMakeFiles/test_extended_xhistogram.dir/main.cpp.o CMakeFiles/test_extended_xhistogram.dir/test_extended_xhistogram.cpp.o -o test_extended_xhistogram  -lpthread 
/usr/bin/ld: CMakeFiles/test_xexpression_holder.dir/main.cpp.o: in function `doctest::Context::run()':
main.cpp:(.text+0x204d0): undefined reference to `__umodsi3'
/usr/bin/ld: main.cpp:(.text+0x204dc): undefined reference to `__umodsi3'
/usr/bin/ld: CMakeFiles/test_xexpression_holder.dir/test_xexpression_holder.cpp.o: in function `nlohmann::detail::dtoa_impl::grisu2_digit_gen(char*, int&, int&, nlohmann::detail::dtoa_impl::diyfp, nlohmann::detail::dtoa_impl::diyfp, nlohmann::detail::dtoa_impl::diyfp)':
test_xexpression_holder.cpp:(.text._ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_[_ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_]+0x298): undefined reference to `__udivsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_[_ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_]+0x2a8): undefined reference to `__udivsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_[_ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_]+0x2c0): undefined reference to `__umodsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_[_ZN8nlohmann6detail9dtoa_impl16grisu2_digit_genEPcRiS3_NS1_5diyfpES4_S4_]+0x2d0): undefined reference to `__umodsi3'
/usr/bin/ld: CMakeFiles/test_xexpression_holder.dir/test_xexpression_holder.cpp.o: in function `unsigned int std::__detail::__to_chars_len<unsigned int>(unsigned int, int)':
test_xexpression_holder.cpp:(.text._ZNSt8__detail14__to_chars_lenIjEEjT_i[_ZNSt8__detail14__to_chars_lenIjEEjT_i]+0xe8): undefined reference to `__udivsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZNSt8__detail14__to_chars_lenIjEEjT_i[_ZNSt8__detail14__to_chars_lenIjEEjT_i]+0xf8): undefined reference to `__udivsi3'
/usr/bin/ld: CMakeFiles/test_xexpression_holder.dir/test_xexpression_holder.cpp.o: in function `std::ostream& xt::detail::xoutput<xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, xt::svector<unsigned int, 4u, std::allocator<unsigned int>, true>, xt::xtensor_expression_tag>, xt::detail::printer<xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, xt::svector<unsigned int, 4u, std::allocator<unsigned int>, true>, xt::xtensor_expression_tag>, void> >(std::ostream&, xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, xt::svector<unsigned int, 4u, std::allocator<unsigned int>, true>, xt::xtensor_expression_tag> const&, std::vector<mpark::variant<int, xt::xrange_adaptor<xt::placeholders::xtuph, int, int>, xt::xrange_adaptor<int, xt::placeholders::xtuph, int>, xt::xrange_adaptor<int, int, xt::placeholders::xtuph>, xt::xrange_adaptor<int, xt::placeholders::xtuph, xt::placeholders::xtuph>, xt::xrange_adaptor<xt::placeholders::xtuph, int, xt::placeholders::xtuph>, xt::xrange_adaptor<xt::placeholders::xtuph, xt::placeholders::xtuph, int>, xt::xrange_adaptor<int, int, int>, xt::xrange_adaptor<xt::placeholders::xtuph, xt::placeholders::xtuph, xt::placeholders::xtuph>, xt::xrange<int>, xt::xstepped_range<int>, xt::xall_tag, xt::xellipsis_tag, xt::xnewaxis_tag>, std::allocator<mpark::variant<int, xt::xrange_adaptor<xt::placeholders::xtuph, int, int>, xt::xrange_adaptor<int, xt::placeholders::xtuph, int>, xt::xrange_adaptor<int, int, xt::placeholders::xtuph>, xt::xrange_adaptor<int, xt::placeholders::xtuph, xt::placeholders::xtuph>, xt::xrange_adaptor<xt::placeholders::xtuph, int, xt::placeholders::xtuph>, xt::xrange_adaptor<xt::placeholders::xtuph, xt::placeholders::xtuph, int>, xt::xrange_adaptor<int, int, int>, xt::xrange_adaptor<xt::placeholders::xtuph, xt::placeholders::xtuph, xt::placeholders::xtuph>, xt::xrange<int>, xt::xstepped_range<int>, xt::xall_tag, xt::xellipsis_tag, xt::xnewaxis_tag> > >&, xt::detail::printer<xt::xarray_container<xt::uvector<double, std::allocator<double> >, (xt::layout_type)1, xt::svector<unsigned int, 4u, std::allocator<unsigned int>, true>, xt::xtensor_expression_tag>, void>&, unsigned int, int, unsigned int, unsigned int)':
test_xexpression_holder.cpp:(.text._ZN2xt6detail7xoutputINS_16xarray_containerINS_7uvectorIdSaIdEEELNS_11layout_typeE1ENS_7svectorIjLj4ESaIjELb1EEENS_22xtensor_expression_tagEEENS0_7printerISB_vEEEERSoSE_RKT_RSt6vectorIN5mpark7variantIJiNS_14xrange_adaptorINS_12placeholders5xtuphEiiEENSL_IiSN_iEENSL_IiiSN_EENSL_IiSN_SN_EENSL_ISN_iSN_EENSL_ISN_SN_iEENSL_IiiiEENSL_ISN_SN_SN_EENS_6xrangeIiEENS_14xstepped_rangeIiEENS_8xall_tagENS_13xellipsis_tagENS_12xnewaxis_tagEEEESaIS13_EERT0_jijj[_ZN2xt6detail7xoutputINS_16xarray_containerINS_7uvectorIdSaIdEEELNS_11layout_typeE1ENS_7svectorIjLj4ESaIjELb1EEENS_22xtensor_expression_tagEEENS0_7printerISB_vEEEERSoSE_RKT_RSt6vectorIN5mpark7variantIJiNS_14xrange_adaptorINS_12placeholders5xtuphEiiEENSL_IiSN_iEENSL_IiiSN_EENSL_IiSN_SN_EENSL_ISN_iSN_EENSL_ISN_SN_iEENSL_IiiiEENSL_ISN_SN_SN_EENS_6xrangeIiEENS_14xstepped_rangeIiEENS_8xall_tagENS_13xellipsis_tagENS_12xnewaxis_tagEEEESaIS13_EERT0_jijj]+0x124): undefined reference to `__udivsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZN2xt6detail7xoutputINS_16xarray_containerINS_7uvectorIdSaIdEEELNS_11layout_typeE1ENS_7svectorIjLj4ESaIjELb1EEENS_22xtensor_expression_tagEEENS0_7printerISB_vEEEERSoSE_RKT_RSt6vectorIN5mpark7variantIJiNS_14xrange_adaptorINS_12placeholders5xtuphEiiEENSL_IiSN_iEENSL_IiiSN_EENSL_IiSN_SN_EENSL_ISN_iSN_EENSL_ISN_SN_iEENSL_IiiiEENSL_ISN_SN_SN_EENS_6xrangeIiEENS_14xstepped_rangeIiEENS_8xall_tagENS_13xellipsis_tagENS_12xnewaxis_tagEEEESaIS13_EERT0_jijj[_ZN2xt6detail7xoutputINS_16xarray_containerINS_7uvectorIdSaIdEEELNS_11layout_typeE1ENS_7svectorIjLj4ESaIjELb1EEENS_22xtensor_expression_tagEEENS0_7printerISB_vEEEERSoSE_RKT_RSt6vectorIN5mpark7variantIJiNS_14xrange_adaptorINS_12placeholders5xtuphEiiEENSL_IiSN_iEENSL_IiiSN_EENSL_IiSN_SN_EENSL_ISN_iSN_EENSL_ISN_SN_iEENSL_IiiiEENSL_ISN_SN_SN_EENS_6xrangeIiEENS_14xstepped_rangeIiEENS_8xall_tagENS_13xellipsis_tagENS_12xnewaxis_tagEEEESaIS13_EERT0_jijj]+0x134): undefined reference to `__udivsi3'
/usr/bin/ld: CMakeFiles/test_xexpression_holder.dir/test_xexpression_holder.cpp.o: in function `xt::xstepped_range<int>::xstepped_range(int, int, int)':
test_xexpression_holder.cpp:(.text._ZN2xt14xstepped_rangeIiEC2Eiii[_ZN2xt14xstepped_rangeIiEC5Eiii]+0x64): undefined reference to `__divsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZN2xt14xstepped_rangeIiEC2Eiii[_ZN2xt14xstepped_rangeIiEC5Eiii]+0x74): undefined reference to `__divsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZN2xt14xstepped_rangeIiEC2Eiii[_ZN2xt14xstepped_rangeIiEC5Eiii]+0xb0): undefined reference to `__modsi3'
/usr/bin/ld: test_xexpression_holder.cpp:(.text._ZN2xt14xstepped_rangeIiEC2Eiii[_ZN2xt14xstepped_rangeIiEC5Eiii]+0xc0): undefined reference to `__modsi3'
collect2: error: ld returned 1 exit status
make[3]: *** [test/CMakeFiles/test_xexpression_holder.dir/build.make:116: test/test_xexpression_holder] Error 1

The complete build log can be found at https://buildd.debian.org/status/fetch.php?pkg=xtensor&arch=mipsel&ver=0.23.10-7&stamp=1633596751&raw=0

The undefined reference seems to be a regression in the sense that test_extended_xhistogram previously linked successfully with 0.22.0. The mipsel build failed in that case for a different reason (virtual memory exhausted). 0.22.0 build log at https://buildd.debian.org/status/fetch.php?pkg=xtensor&arch=mipsel&ver=0.22.0-5&stamp=1625770623&raw=0

drew-parsons commented 2 years ago

There's a strange reproduceability in the build failure. Attempting to build again gets a different error message,

[ 39%] Linking CXX executable test_xreducer
cd /<<PKGBUILDDIR>>/obj-mipsel-linux-gnu/test && /usr/bin/cmake -E cmake_link_script CMakeFiles/test_xreducer.dir/link.txt --verbose=1
/usr/bin/c++ -O0 -std=c++14 -Wunused-parameter -Wextra -Wreorder -Wconversion -Wsign-conversion -Wold-style-cast -Wunused-variable -ftemplate-backtrace-limit=0 -Wl,-z,relro -rdynamic CMakeFiles/test_xreducer.dir/main.cpp.o CMakeFiles/test_xreducer.dir/test_xreducer.cpp.o -o test_xreducer  -lpthread 
cd /<<PKGBUILDDIR>>/obj-mipsel-linux-gnu/test && /usr/bin/c++  -I/<<PKGBUILDDIR>>/include -O0 -std=c++14 -Wunused-parameter -Wextra -Wreorder -Wconversion -Wsign-conversion -Wold-style-cast -Wunused-variable -ftemplate-backtrace-limit=0 -MD -MT test/CMakeFiles/test_xexpression_traits.dir/main.cpp.o -MF CMakeFiles/test_xexpression_traits.dir/main.cpp.o.d -o CMakeFiles/test_xexpression_traits.dir/main.cpp.o -c /<<PKGBUILDDIR>>/test/main.cpp
CMakeFiles/test_xreducer.dir/test_xreducer.cpp.o: in function `__gthread_active_p()':
test_xreducer.cpp:(.text+0x1c): relocation truncated to fit: R_MIPS_GOT16 against `__pthread_key_create@@GLIBC_2.0'
CMakeFiles/test_xreducer.dir/test_xreducer.cpp.o: in function `xt::xreducer_features::xreducer_features()':
test_xreducer.cpp:(.text+0x23c): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
test_xreducer.cpp:(.text+0x2ac): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
CMakeFiles/test_xreducer.dir/test_xreducer.cpp.o: in function `xt::_DOCTEST_ANON_FUNC_2()':
test_xreducer.cpp:(.text+0x418): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xreducer.cpp:(.text+0x4b0): relocation truncated to fit: R_MIPS_CALL16 against `__cxa_begin_catch@@CXXABI_1.3'
test_xreducer.cpp:(.text+0x4e0): relocation truncated to fit: R_MIPS_CALL16 against `__cxa_end_catch@@CXXABI_1.3'
test_xreducer.cpp:(.text+0x504): relocation truncated to fit: R_MIPS_CALL16 against `__cxa_end_catch@@CXXABI_1.3'
test_xreducer.cpp:(.text+0x5a4): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
CMakeFiles/test_xreducer.dir/test_xreducer.cpp.o: in function `xt::_DOCTEST_ANON_FUNC_4()':
test_xreducer.cpp:(.text+0x70c): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xreducer.cpp:(.text+0x7a4): relocation truncated to fit: R_MIPS_CALL16 against `__cxa_begin_catch@@CXXABI_1.3'
test_xreducer.cpp:(.text+0x7d4): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status
make[3]: *** [test/CMakeFiles/test_xreducer.dir/build.make:116: test/test_xreducer] Error 1
make[3]: Leaving directory '/<<PKGBUILDDIR>>/obj-mipsel-linux-gnu'
make[2]: *** [CMakeFiles/Makefile2:1706: test/CMakeFiles/test_xreducer.dir/all] Error 2

Full log at https://buildd.debian.org/status/fetch.php?pkg=xtensor&arch=mipsel&ver=0.23.10-7&stamp=1633621040&raw=0

Something going bad with mipsel builds, evidently not just umodsi3, divsi3 I'll update the title to reflect more general build problems.

drew-parsons commented 2 years ago

Weighing this "relocation truncated to fit" against earlier "virtual memory exhausted" errors, it looks like xtensor is just to big for mipsel. Are there strategies or cmake configurations to bring it back down to manageable size? I'm already trying -O0, it's not enough.

JohanMabille commented 2 years ago

@drew-parsons one strategy would be to split the tests in many executables (one executable per test file, it is already partially done). The goal of the current implementation was to be able to build and run only a single test (instead of waiting for the whole test suite to build when you change something in xtensor). It may not be convenient for running all the tests, but that's something we can definitely improve.

drew-parsons commented 2 years ago

The test configuration distinguishes COMMON_BASE from XTENSOR_TESTS. I've been assuming COMMON_BASE provides test infrastructure, and the actual tests are the XTENSOR_TESTS. But even if XTENSOR_TESTS is reduced to just one file, the problem (relocation truncated in test_xreducer.cpp) still happens.

And the problem is not simply test_xreducer.cpp. Removing it from COMMON_BASE, the problem just jumps to another file,

CMakeFiles/test_xtensor_lib_m.dir/test_xmath_result_type.cpp.o: in function `xt::_DOCTEST_ANON_FUNC_2()':
test_xmath_result_type.cpp:(.text+0x178): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x26c): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x360): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x454): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x548): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x63c): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x730): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x824): relocation truncated to fit: R_MIPS_CALL16 against `raise@@GLIBC_2.0'
test_xmath_result_type.cpp:(.text+0x2bdc): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
test_xmath_result_type.cpp:(.text+0x2bf8): relocation truncated to fit: R_MIPS_CALL16 against `__cxa_begin_catch@@CXXABI_1.3'
test_xmath_result_type.cpp:(.text+0x2c28): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status
drew-parsons commented 2 years ago

There have been two separate problems with the xtensor build on mipsel (debian build).

Firstly, virtual memory exceeded (this also affects other 32-bit architectures like i386). Ultimately this was caused by building with debug symbols (-g). That can be fixed obviously by not using -g, or to force the point by specifying -g0. That alone is enough to avoid exceeding memory, but more memory gain can be made by optimizing with -Os.

Secondly, the "relocation truncated" problem. This is related to a quirk in specific mipsel CPU models, and can be worked around by adding the -mxgot build flag. But the problem is triggered by using -march=native in the test build. That can be avoided by using the cmake configuration option -Darch_native_supported=OFF

In summary, mipsel will build with compiler flags

-Os -g0

and cmake configuration flag

-Darch_native_supported=OFF

Since this can be resolved with the architecture build configuration, xtensor code does not need to be changed (unless -march=native should be deactivated for all arches). So this Issue can be closed now.