xtensor
xtensor copied to clipboard
xsort tests failing
We recently updated to VS 2022 (with MSVC 14.32.31326) and now get a crash when calling xtensor code (more precisly xt::argmax
). I tried updating the library but the problem remains, in fact I realize that even the test suite for xsorts fails. It only happens for (any type of) release build and not for the debug build. Below is a MWE.
# include <xtensor/xarray.hpp>
# include <xtensor/xsort.hpp>
int main()
{
xt::xarray<double> data{ {1, 2, 3}, {2, 1, 0} };
return xt::argmax( data )() == 2
? 0
: 1;
}
Possible hint: The compiler throws a C4244 warning on building the tests.
Thanks for reporting. Do you have a more detailed compiler error stream (what line, what error message, ...)? That could give hints on how to fix it. Beyond that, we should CI for this
Not really. When running the above snippet I get:
Exception thrown at 0x00007FF7403C1ECE in simple_example.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
I've run into this as well with the same MSVC version. Same result with xtensor 0.23.3, 0.24.1, and master
I discovered that in Debug
mode, it runs successfully, however not when in Release
mode.
Can see it in action on godbolt
stack trace from ReleaseWithDebug build
1 xt::xstrided_container<xt::xtensor_container<xt::uvector<unsigned __int64>,0,1,xt::xtensor_expression_tag>>::resize<std::array<unsigned __int64,0>> xcontainer.hpp 958 0x7ff704e7e2fe
2 xt::xtensor_container<xt::uvector<unsigned __int64>,0,1,xt::xtensor_expression_tag>::xtensor_container<xt::uvector<unsigned __int64>,0,1,xt::xtensor_expression_tag> xtensor.hpp 425 0x7ff704e84b0f
3 xt::argmax<1,xt::xtensor_container<xt::uvector<double>,1,1,xt::xtensor_expression_tag>> xsort.hpp 888 0x7ff704e6f566
4 foo main.cpp 19 0x7ff704e8d3e5
5 main main.cpp 33 0x7ff704e93d79
6 __scrt_common_main_seh exe_common.inl 288 0x7ff704e94720
7 BaseThreadInitThunk KERNEL32 0x7ffefdce7034
8 RtlUserThreadStart ntdll 0x7ffeffcc2651
I was able to printf
debug a bit further
debugging
This is where the debugger stops, presumably becausecompute_strides
is inlined.
// xcontainer.hpp ~958
template <class D>
template <class S>
inline void xstrided_container<D>::resize(S&& shape, bool force)
{
// ...
size_type data_size = compute_strides<D::static_layout>(m_shape, m_layout, m_strides, m_backstrides);
I just began adding std::cout
debugging lines. I found that with the second line uncommented, the program works correctly. Without it, the program just gives up w/o even an exception.
// xstrides.hpp ~453
template <layout_type L, class shape_type, class strides_type, class bs_ptr>
inline std::size_t compute_strides(const shape_type& shape, layout_type l,
strides_type& strides, bs_ptr bs)
{
using strides_value_type = typename std::decay_t<strides_type>::value_type;
strides_value_type data_size = 1;
if (L == layout_type::row_major || l == layout_type::row_major)
{
std::cout << "This prints" << std::endl;
for (std::size_t i = shape.size(); i != 0; --i)
{
// std::cout << "If uncommented, program works" << std::endl;
strides[i - 1] = data_size;
data_size = strides[i - 1] * static_cast<strides_value_type>(shape[i - 1]);
adapt_strides(shape, strides, bs, i - 1);
}
}
else
{
for (std::size_t i = 0; i < shape.size(); ++i)
{
strides[i] = data_size;
data_size = strides[i] * static_cast<strides_value_type>(shape[i]);
adapt_strides(shape, strides, bs, i);
}
}
return static_cast<std::size_t>(data_size);
}
I hope some of that info might be helpful in discovering what's going on