xtensor icon indicating copy to clipboard operation
xtensor copied to clipboard

xsort tests failing

Open fweidling opened this issue 2 years ago • 3 comments

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.

fweidling avatar Jun 28 '22 12:06 fweidling

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

tdegeus avatar Jul 26 '22 08:07 tdegeus

Not really. When running the above snippet I get:

Exception thrown at 0x00007FF7403C1ECE in simple_example.exe: 0xC0000005: Access violation reading location 0x0000000000000000.

fweidling avatar Jul 27 '22 07:07 fweidling

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 because compute_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

sg-james avatar Aug 01 '22 18:08 sg-james