From 66a835c8cd3805428452348c07f67f55493adda3 Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Mon, 12 Nov 2018 11:10:16 +0100 Subject: [PATCH 0001/1112] Cosmetic changes on steppers --- include/xtensor/xfunction.hpp | 50 +++++------ include/xtensor/xiterator.hpp | 117 +++++++++++++------------ include/xtensor/xstrided_view_base.hpp | 4 +- 3 files changed, 86 insertions(+), 85 deletions(-) diff --git a/include/xtensor/xfunction.hpp b/include/xtensor/xfunction.hpp index 9ec4d99fb..033b29a73 100644 --- a/include/xtensor/xfunction.hpp +++ b/include/xtensor/xfunction.hpp @@ -527,8 +527,8 @@ namespace xt using shape_type = typename xfunction_type::shape_type; - template - xfunction_stepper(const xfunction_type* func, It&&... it) noexcept; + template + xfunction_stepper(const xfunction_type* func, St&&... st) noexcept; void step(size_type dim); void step_back(size_type dim); @@ -559,7 +559,7 @@ namespace xt value_type step_leading_impl(std::index_sequence); const xfunction_type* p_f; - std::tuple::const_stepper...> m_it; + std::tuple::const_stepper...> m_st; }; /********************************* @@ -1075,66 +1075,66 @@ namespace xt ************************************/ template - template - inline xfunction_stepper::xfunction_stepper(const xfunction_type* func, It&&... it) noexcept - : p_f(func), m_it(std::forward(it)...) + template + inline xfunction_stepper::xfunction_stepper(const xfunction_type* func, St&&... st) noexcept + : p_f(func), m_st(std::forward(st)...) { } template inline void xfunction_stepper::step(size_type dim) { - auto f = [dim](auto& it) { it.step(dim); }; - for_each(f, m_it); + auto f = [dim](auto& st) { st.step(dim); }; + for_each(f, m_st); } template inline void xfunction_stepper::step_back(size_type dim) { - auto f = [dim](auto& it) { it.step_back(dim); }; - for_each(f, m_it); + auto f = [dim](auto& st) { st.step_back(dim); }; + for_each(f, m_st); } template inline void xfunction_stepper::step(size_type dim, size_type n) { - auto f = [dim, n](auto& it) { it.step(dim, n); }; - for_each(f, m_it); + auto f = [dim, n](auto& st) { st.step(dim, n); }; + for_each(f, m_st); } template inline void xfunction_stepper::step_back(size_type dim, size_type n) { - auto f = [dim, n](auto& it) { it.step_back(dim, n); }; - for_each(f, m_it); + auto f = [dim, n](auto& st) { st.step_back(dim, n); }; + for_each(f, m_st); } template inline void xfunction_stepper::reset(size_type dim) { - auto f = [dim](auto& it) { it.reset(dim); }; - for_each(f, m_it); + auto f = [dim](auto& st) { st.reset(dim); }; + for_each(f, m_st); } template inline void xfunction_stepper::reset_back(size_type dim) { - auto f = [dim](auto& it) { it.reset_back(dim); }; - for_each(f, m_it); + auto f = [dim](auto& st) { st.reset_back(dim); }; + for_each(f, m_st); } template inline void xfunction_stepper::to_begin() { - auto f = [](auto& it) { it.to_begin(); }; - for_each(f, m_it); + auto f = [](auto& st) { st.to_begin(); }; + for_each(f, m_st); } template inline void xfunction_stepper::to_end(layout_type l) { - auto f = [l](auto& it) { it.to_end(l); }; - for_each(f, m_it); + auto f = [l](auto& st) { st.to_end(l); }; + for_each(f, m_st); } template @@ -1147,14 +1147,14 @@ namespace xt template inline auto xfunction_stepper::deref_impl(std::index_sequence) const -> reference { - return (p_f->m_f)(*std::get(m_it)...); + return (p_f->m_f)(*std::get(m_st)...); } template template inline ST xfunction_stepper::step_simd_impl(std::index_sequence) { - return (p_f->m_f.simd_apply)(std::get(m_it).template + return (p_f->m_f.simd_apply)(std::get(m_st).template step_simd, ST, typename xfunction_type::simd_argument_type @@ -1173,7 +1173,7 @@ namespace xt inline auto xfunction_stepper::step_leading_impl(std::index_sequence) -> value_type { - return (p_f->m_f)(std::get(m_it).step_leading()...); + return (p_f->m_f)(std::get(m_st).step_leading()...); } template diff --git a/include/xtensor/xiterator.hpp b/include/xtensor/xiterator.hpp index d7496b492..2cd117f9f 100644 --- a/include/xtensor/xiterator.hpp +++ b/include/xtensor/xiterator.hpp @@ -271,24 +271,24 @@ namespace xt struct LAYOUT_FORBIDEN_FOR_XITERATOR; } - template - class xiterator : public xtl::xrandom_access_iterator_base, - typename It::value_type, - typename It::difference_type, - typename It::pointer, - typename It::reference>, + template + class xiterator : public xtl::xrandom_access_iterator_base, + typename St::value_type, + typename St::difference_type, + typename St::pointer, + typename St::reference>, private detail::shape_storage { public: - using self_type = xiterator; + using self_type = xiterator; - using subiterator_type = It; - using value_type = typename subiterator_type::value_type; - using reference = typename subiterator_type::reference; - using pointer = typename subiterator_type::pointer; - using difference_type = typename subiterator_type::difference_type; - using size_type = typename subiterator_type::size_type; + using stepper_type = St; + using value_type = typename stepper_type::value_type; + using reference = typename stepper_type::reference; + using pointer = typename stepper_type::pointer; + using difference_type = typename stepper_type::difference_type; + using size_type = typename stepper_type::size_type; using iterator_category = std::random_access_iterator_tag; using private_base = detail::shape_storage; @@ -297,8 +297,9 @@ namespace xt using index_type = xindex_type_t; xiterator() = default; + // end_index means either reverse_iterator && !end or !reverse_iterator && end - xiterator(It it, shape_param_type shape, bool end_index); + xiterator(St st, shape_param_type shape, bool end_index); self_type& operator++(); self_type& operator--(); @@ -316,20 +317,20 @@ namespace xt private: - subiterator_type m_it; + stepper_type m_st; index_type m_index; difference_type m_linear_index; using checking_type = typename detail::LAYOUT_FORBIDEN_FOR_XITERATOR::type; }; - template - bool operator==(const xiterator& lhs, - const xiterator& rhs); + template + bool operator==(const xiterator& lhs, + const xiterator& rhs); - template - bool operator<(const xiterator& lhs, - const xiterator& rhs); + template + bool operator<(const xiterator& lhs, + const xiterator& rhs); /********************* * xbounded_iterator * @@ -471,7 +472,7 @@ namespace xt { if (dim >= m_offset) { - using strides_value_type = decltype(p_c->strides()[0]); + using strides_value_type = typename std::decay_tstrides())>::value_type; m_it += difference_type(static_cast(n) * p_c->strides()[dim - m_offset]); } } @@ -481,7 +482,7 @@ namespace xt { if (dim >= m_offset) { - using strides_value_type = decltype(p_c->strides()[0]); + using strides_value_type = typename std::decay_tstrides())>::value_type; m_it -= difference_type(static_cast(n) * p_c->strides()[dim - m_offset]); } } @@ -971,9 +972,9 @@ namespace xt }; } - template - inline xiterator::xiterator(It it, shape_param_type shape, bool end_index) - : private_base(shape), m_it(it), + template + inline xiterator::xiterator(St st, shape_param_type shape, bool end_index) + : private_base(shape), m_st(st), m_index(end_index ? xtl::forward_sequence(this->shape()) : xtl::make_sequence(this->shape().size(), size_type(0))), m_linear_index(0) @@ -992,94 +993,94 @@ namespace xt } } - template - inline auto xiterator::operator++() -> self_type& + template + inline auto xiterator::operator++() -> self_type& { - stepper_tools::increment_stepper(m_it, m_index, this->shape()); + stepper_tools::increment_stepper(m_st, m_index, this->shape()); ++m_linear_index; return *this; } - template - inline auto xiterator::operator--() -> self_type& + template + inline auto xiterator::operator--() -> self_type& { - stepper_tools::decrement_stepper(m_it, m_index, this->shape()); + stepper_tools::decrement_stepper(m_st, m_index, this->shape()); --m_linear_index; return *this; } - template - inline auto xiterator::operator+=(difference_type n) -> self_type& + template + inline auto xiterator::operator+=(difference_type n) -> self_type& { if (n >= 0) { - stepper_tools::increment_stepper(m_it, m_index, this->shape(), static_cast(n)); + stepper_tools::increment_stepper(m_st, m_index, this->shape(), static_cast(n)); } else { - stepper_tools::decrement_stepper(m_it, m_index, this->shape(), static_cast(-n)); + stepper_tools::decrement_stepper(m_st, m_index, this->shape(), static_cast(-n)); } m_linear_index += n; return *this; } - template - inline auto xiterator::operator-=(difference_type n) -> self_type& + template + inline auto xiterator::operator-=(difference_type n) -> self_type& { if (n >= 0) { - stepper_tools::decrement_stepper(m_it, m_index, this->shape(), static_cast(n)); + stepper_tools::decrement_stepper(m_st, m_index, this->shape(), static_cast(n)); } else { - stepper_tools::increment_stepper(m_it, m_index, this->shape(), static_cast(-n)); + stepper_tools::increment_stepper(m_st, m_index, this->shape(), static_cast(-n)); } m_linear_index -= n; return *this; } - template - inline auto xiterator::operator-(const self_type& rhs) const -> difference_type + template + inline auto xiterator::operator-(const self_type& rhs) const -> difference_type { return m_linear_index - rhs.m_linear_index; } - template - inline auto xiterator::operator*() const -> reference + template + inline auto xiterator::operator*() const -> reference { - return *m_it; + return *m_st; } - template - inline auto xiterator::operator->() const -> pointer + template + inline auto xiterator::operator->() const -> pointer { - return &(*m_it); + return &(*m_st); } - template - inline bool xiterator::equal(const xiterator& rhs) const + template + inline bool xiterator::equal(const xiterator& rhs) const { XTENSOR_ASSERT(this->shape() == rhs.shape()); return m_linear_index == rhs.m_linear_index; } - template - inline bool xiterator::less_than(const xiterator& rhs) const + template + inline bool xiterator::less_than(const xiterator& rhs) const { XTENSOR_ASSERT(this->shape() == rhs.shape()); return m_linear_index < rhs.m_linear_index; } - template - inline bool operator==(const xiterator& lhs, - const xiterator& rhs) + template + inline bool operator==(const xiterator& lhs, + const xiterator& rhs) { return lhs.equal(rhs); } - template - bool operator<(const xiterator& lhs, - const xiterator& rhs) + template + bool operator<(const xiterator& lhs, + const xiterator& rhs) { return lhs.less_than(rhs); } diff --git a/include/xtensor/xstrided_view_base.hpp b/include/xtensor/xstrided_view_base.hpp index 19078e457..809e92cbe 100644 --- a/include/xtensor/xstrided_view_base.hpp +++ b/include/xtensor/xstrided_view_base.hpp @@ -959,7 +959,7 @@ namespace xt base_type::resize(dimension); auto old_shape = shape; - using old_strides_vt = std::decay_t; + using old_strides_value_type = typename std::decay_t::value_type; std::ptrdiff_t axis_skip = 0; std::size_t idx = 0, i = 0, i_ax = 0; @@ -972,7 +972,7 @@ namespace xt auto ptr = xtl::get_if(&slices[i]); if (ptr != nullptr) { - auto slice0 = static_cast(*ptr); + auto slice0 = static_cast(*ptr); new_offset += static_cast(slice0 * old_strides[i_ax]); } else if (xtl::get_if(&slices[i]) != nullptr) From feda8c756091cd0f7b7e8ff578a496dd41bda9f8 Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Mon, 12 Nov 2018 17:01:18 +0100 Subject: [PATCH 0002/1112] Add iterator tests --- include/xtensor/xview.hpp | 2 +- test/test_xiterator.cpp | 92 ++++++++++++++++++++++++--------------- 2 files changed, 57 insertions(+), 37 deletions(-) diff --git a/include/xtensor/xview.hpp b/include/xtensor/xview.hpp index 5d7eab9db..8cf3bc73e 100644 --- a/include/xtensor/xview.hpp +++ b/include/xtensor/xview.hpp @@ -1620,7 +1620,7 @@ namespace xt for (size_type i = 0; i != m_e.dimension(); ++i) { size_type k = newaxis_skip(i); - std::advance(first, k - i); + std::advance(first, difference_type(k - i)); if (first != last) { index[i] = k < sizeof...(S) ? diff --git a/test/test_xiterator.cpp b/test/test_xiterator.cpp index 38886cd0d..d1643dba7 100644 --- a/test/test_xiterator.cpp +++ b/test/test_xiterator.cpp @@ -19,6 +19,7 @@ namespace xt class xiterator_test : public ::testing::Test { public: + using result_type = R; }; @@ -36,13 +37,16 @@ namespace xt vector_type data = result.storage(); xarray_adaptor a(data, result.shape(), result.strides()); - size_type nb_inc = L == layout_type::row_major ? + auto offset = shape.size() - a.dimension(); + auto broadcasting_stride = std::accumulate(shape.cbegin(), shape.cbegin() + offset, size_type(1), std::multiplies()); + size_type nb_inc = (L == layout_type::row_major ? shape.back() * shape[shape.size() - 2] + 1 : - shape.front() * shape[1] + 1; + broadcasting_stride * (result.shape().front() * result.shape()[1] + 1)); + int expected = a(1, 0, 1); - auto iter = a.template begin(); - auto iter2 = a.template begin(); + auto iter = a.template begin(shape); + auto iter2 = a.template begin(shape); for (size_type i = 0; i < nb_inc; ++i) { ++iter; @@ -90,9 +94,13 @@ namespace xt using vector_type = typename R::vector_type; vector_type data = result.storage(); xarray_adaptor a(data, result.shape(), result.strides()); - difference_type nb_inc = difference_type(L == layout_type::row_major ? + + auto offset = shape.size() - a.dimension(); + auto broadcasting_stride = std::accumulate(shape.cbegin(), shape.cbegin() + offset, difference_type(1), std::multiplies()); + auto nb_inc = difference_type(L == layout_type::row_major ? shape.back() * shape[shape.size() - 2] + 1 : - shape.front() * shape[1] + 1); + broadcasting_stride * difference_type(result.shape().front() * result.shape()[1] + 1)); + int expected = a(1, 0, 1); auto iter = a.template begin(); @@ -136,17 +144,17 @@ namespace xt } } - template - void test_end(const R& result) + template + void test_end(const R& result, const S& shape) { using size_type = typename R::size_type; using vector_type = typename R::vector_type; vector_type data = result.storage(); xarray_adaptor a(data, result.shape(), result.strides()); - size_type size = a.size(); - auto iter = a.template begin(); - auto last = a.template end(); + size_type size = compute_size(shape); + auto iter = a.template begin(shape); + auto last = a.template end(shape); for (size_type i = 0; i < size; ++i) { ++iter; @@ -161,7 +169,7 @@ namespace xt typename TestFixture::result_type rm; { SCOPED_TRACE("same shape - row_major iterator"); - test_end(rm); + test_end(rm, rm.shape()); } { @@ -169,12 +177,12 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_end(rm); + test_end(rm, sh); } { SCOPED_TRACE("same shape - column_major iterator"); - test_end(rm); + test_end(rm, rm.shape()); } { @@ -182,7 +190,7 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_end(rm); + test_end(rm, sh); } } @@ -193,13 +201,17 @@ namespace xt using vector_type = typename R::vector_type; vector_type data = result.storage(); xarray_adaptor a(data, result.shape(), result.strides()); - size_type nb_inc = L == layout_type::row_major ? + + auto offset = shape.size() - a.dimension(); + auto broadcasting_stride = std::accumulate(shape.cbegin(), shape.cbegin() + offset, size_type(1), std::multiplies()); + size_type nb_inc = (L == layout_type::row_major ? shape.back() * shape[shape.size() - 2] + 1 : - shape.front() * shape[1] + 1; + broadcasting_stride * (result.shape().front() * result.shape()[1] + 1)); + int expected = a(1, 1, 2); - auto iter = a.template rbegin(); - auto iter2 = a.template rbegin(); + auto iter = a.template rbegin(shape); + auto iter2 = a.template rbegin(shape); for (size_type i = 0; i < nb_inc; ++i) { ++iter; @@ -222,7 +234,7 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_decrement(rm, rm.shape()); + test_decrement(rm, sh); } { @@ -235,7 +247,7 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_decrement(rm, rm.shape()); + test_decrement(rm, sh); } } @@ -246,13 +258,17 @@ namespace xt using vector_type = typename R::vector_type; vector_type data = result.storage(); xarray_adaptor a(data, result.shape(), result.strides()); - difference_type nb_inc = difference_type(L == layout_type::row_major ? + + auto offset = shape.size() - a.dimension(); + auto broadcasting_stride = std::accumulate(shape.cbegin(), shape.cbegin() + offset, difference_type(1), std::multiplies()); + auto nb_inc = difference_type(L == layout_type::row_major ? shape.back() * shape[shape.size() - 2] + 1 : - shape.front() * shape[1] + 1); + broadcasting_stride * difference_type(result.shape().front() * result.shape()[1] + 1)); + int expected = a(1, 1, 2); - auto iter = a.template rbegin(); - auto iter2 = a.template rbegin(); + auto iter = a.template rbegin(shape); + auto iter2 = a.template rbegin(shape); iter += nb_inc; auto iter3 = iter2 + nb_inc; @@ -274,7 +290,7 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_random_decrement(rm, rm.shape()); + test_random_decrement(rm, sh); } { @@ -287,21 +303,25 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_random_decrement(rm, rm.shape()); + test_random_decrement(rm, sh); } } - template - void test_rend(const R& result) + template + void test_rend(const R& result, const S& shape) { using size_type = typename R::size_type; using vector_type = typename R::vector_type; vector_type data = result.storage(); xarray_adaptor a(data, result.shape(), result.strides()); - size_type size = a.size(); - auto iter = a.template rbegin(); - auto last = a.template rend(); + size_type size = compute_size(shape); + auto iter = a.template rbegin(shape); + auto last = a.template rend(shape); + + EXPECT_EQ(*iter, data.back()) << "dereferencing rbegin does not result in last element"; + EXPECT_EQ(*last, data.front()) << "dereferencing rend does not result in first element"; + for (size_type i = 0; i < size; ++i) { ++iter; @@ -315,7 +335,7 @@ namespace xt typename TestFixture::result_type rm; { SCOPED_TRACE("same shape - row_major iterator"); - test_rend(rm); + test_rend(rm, rm.shape()); } { @@ -323,12 +343,12 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_rend(rm); + test_rend(rm, sh); } { SCOPED_TRACE("same shape - column_major iterator"); - test_rend(rm); + test_rend(rm, rm.shape()); } { @@ -336,7 +356,7 @@ namespace xt layout_result<>::shape_type sh = rm.shape(); sh.insert(sh.begin(), 2); sh.insert(sh.begin(), 4); - test_rend(rm); + test_rend(rm, sh); } } From 0f914df34372514b65f8c3959a7cb03a1672578b Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Mon, 12 Nov 2018 17:00:30 +0100 Subject: [PATCH 0003/1112] Fixup stepper_end logic --- include/xtensor/xcontainer.hpp | 24 ++++++++++++------------ include/xtensor/xdynamic_view.hpp | 23 +++++++++++------------ include/xtensor/xiterator.hpp | 2 +- include/xtensor/xstrided_view.hpp | 23 +++++++++++------------ include/xtensor/xstrides.hpp | 31 +++++++++++++++++++++++-------- include/xtensor/xview.hpp | 23 +++++++++++------------ 6 files changed, 69 insertions(+), 57 deletions(-) diff --git a/include/xtensor/xcontainer.hpp b/include/xtensor/xcontainer.hpp index 91f3e51b8..e8ee1c542 100644 --- a/include/xtensor/xcontainer.hpp +++ b/include/xtensor/xcontainer.hpp @@ -223,8 +223,8 @@ namespace xt container_iterator data_xbegin() noexcept; const_container_iterator data_xbegin() const noexcept; - container_iterator data_xend(layout_type l) noexcept; - const_container_iterator data_xend(layout_type l) const noexcept; + container_iterator data_xend(layout_type l, size_type offset) noexcept; + const_container_iterator data_xend(layout_type l, size_type offset) const noexcept; protected: @@ -238,7 +238,7 @@ namespace xt friend class xstepper; template - It data_xend_impl(It end, layout_type l) const noexcept; + It data_xend_impl(It begin, layout_type l, size_type offset) const noexcept; inner_shape_type& mutable_shape(); inner_strides_type& mutable_strides(); @@ -335,9 +335,9 @@ namespace xt template template - inline It xcontainer::data_xend_impl(It end, layout_type l) const noexcept + inline It xcontainer::data_xend_impl(It begin, layout_type l, size_type offset) const noexcept { - return strided_data_end(*this, end, l); + return strided_data_end(*this, begin, l, offset); } template @@ -751,7 +751,7 @@ namespace xt inline auto xcontainer::stepper_end(const S& shape, layout_type l) noexcept -> stepper { size_type offset = shape.size() - dimension(); - return stepper(static_cast(this), data_xend(l), offset); + return stepper(static_cast(this), data_xend(l, offset), offset); } template @@ -767,7 +767,7 @@ namespace xt inline auto xcontainer::stepper_end(const S& shape, layout_type l) const noexcept -> const_stepper { size_type offset = shape.size() - dimension(); - return const_stepper(static_cast(this), data_xend(l), offset); + return const_stepper(static_cast(this), data_xend(l, offset), offset); } template @@ -779,19 +779,19 @@ namespace xt template inline auto xcontainer::data_xbegin() const noexcept -> const_container_iterator { - return storage().begin(); + return storage().cbegin(); } template - inline auto xcontainer::data_xend(layout_type l) noexcept -> container_iterator + inline auto xcontainer::data_xend(layout_type l, size_type offset) noexcept -> container_iterator { - return data_xend_impl(storage().end(), l); + return data_xend_impl(storage().begin(), l, offset); } template - inline auto xcontainer::data_xend(layout_type l) const noexcept -> const_container_iterator + inline auto xcontainer::data_xend(layout_type l, size_type offset) const noexcept -> const_container_iterator { - return data_xend_impl(storage().end(), l); + return data_xend_impl(storage().cbegin(), l, offset); } template diff --git a/include/xtensor/xdynamic_view.hpp b/include/xtensor/xdynamic_view.hpp index 3473f9c3e..cfc812766 100644 --- a/include/xtensor/xdynamic_view.hpp +++ b/include/xtensor/xdynamic_view.hpp @@ -239,16 +239,16 @@ namespace xt container_iterator data_xbegin() noexcept; const_container_iterator data_xbegin() const noexcept; - container_iterator data_xend(layout_type l) noexcept; - const_container_iterator data_xend(layout_type l) const noexcept; + container_iterator data_xend(layout_type l, size_type offset) noexcept; + const_container_iterator data_xend(layout_type l, size_type offset) const noexcept; template It data_xbegin_impl(It begin) const noexcept; template - It data_xend_impl(It end, layout_type l) const noexcept; + It data_xend_impl(It end, layout_type l, size_type offset) const noexcept; - void assign_temporary_impl(temporary_type&& tmp); + void assign_temporary_impl(temporary_type&& tmp); template offset_type adjust_offset(offset_type offset, T idx, Args... args) const noexcept; @@ -583,7 +583,7 @@ namespace xt inner_strides_type str(base_type::strides()); slice_vector_type svt(m_slices); inner_strides_type adj_str(m_adj_strides); - return rebind_t(std::forward(e), std::move(sh), std::move(str), + return rebind_t(std::forward(e), std::move(sh), std::move(str), base_type::data_offset(), this->layout(), std::move(svt), std::move(adj_str)); } @@ -600,15 +600,15 @@ namespace xt } template - inline auto xdynamic_view::data_xend(layout_type l) noexcept -> container_iterator + inline auto xdynamic_view::data_xend(layout_type l, size_type offset) noexcept -> container_iterator { - return data_xend_impl(this->storage().begin(), l); + return data_xend_impl(this->storage().begin(), l, offset); } template - inline auto xdynamic_view::data_xend(layout_type l) const noexcept -> const_container_iterator + inline auto xdynamic_view::data_xend(layout_type l, size_type offset) const noexcept -> const_container_iterator { - return data_xend_impl(this->storage().cbegin(), l); + return data_xend_impl(this->storage().cbegin(), l, offset); } template @@ -622,10 +622,9 @@ namespace xt template template - inline It xdynamic_view::data_xend_impl(It begin, layout_type l) const noexcept + inline It xdynamic_view::data_xend_impl(It begin, layout_type l, size_type offset) const noexcept { - std::ptrdiff_t end_offset = static_cast(std::accumulate(this->backstrides().begin(), this->backstrides().end(), std::size_t(0))); - return strided_data_end(*this, begin + std::ptrdiff_t(data_offset()) + end_offset + 1, l); + return strided_data_end(*this, begin + std::ptrdiff_t(data_offset()), l, offset); } template diff --git a/include/xtensor/xiterator.hpp b/include/xtensor/xiterator.hpp index 2cd117f9f..e35839c89 100644 --- a/include/xtensor/xiterator.hpp +++ b/include/xtensor/xiterator.hpp @@ -514,7 +514,7 @@ namespace xt template inline void xstepper::to_end(layout_type l) { - m_it = p_c->data_xend(l); + m_it = p_c->data_xend(l, m_offset); } template diff --git a/include/xtensor/xstrided_view.hpp b/include/xtensor/xstrided_view.hpp index 4d55d18f8..0746ef92d 100644 --- a/include/xtensor/xstrided_view.hpp +++ b/include/xtensor/xstrided_view.hpp @@ -251,14 +251,14 @@ namespace xt container_iterator data_xbegin() noexcept; const_container_iterator data_xbegin() const noexcept; - container_iterator data_xend(layout_type l) noexcept; - const_container_iterator data_xend(layout_type l) const noexcept; + container_iterator data_xend(layout_type l, size_type offset) noexcept; + const_container_iterator data_xend(layout_type l, size_type offset) const noexcept; template It data_xbegin_impl(It begin) const noexcept; template - It data_xend_impl(It end, layout_type l) const noexcept; + It data_xend_impl(It end, layout_type l, size_type offset) const noexcept; void assign_temporary_impl(temporary_type&& tmp); @@ -459,7 +459,7 @@ namespace xt inline auto xstrided_view::stepper_end(const ST& shape, layout_type l) -> stepper { size_type offset = shape.size() - dimension(); - return stepper(this, data_xend(l), offset); + return stepper(this, data_xend(l, offset), offset); } template @@ -475,7 +475,7 @@ namespace xt inline auto xstrided_view::stepper_end(const ST& shape, layout_type l) const -> std::enable_if_t::value, STEP> { size_type offset = shape.size() - dimension(); - return const_stepper(this, data_xend(l), offset); + return const_stepper(this, data_xend(l, offset), offset); } template @@ -503,10 +503,9 @@ namespace xt template template - inline It xstrided_view::data_xend_impl(It begin, layout_type l) const noexcept + inline It xstrided_view::data_xend_impl(It begin, layout_type l, size_type offset) const noexcept { - std::ptrdiff_t end_offset = static_cast(std::accumulate(this->backstrides().begin(), this->backstrides().end(), std::size_t(0))); - return strided_data_end(*this, begin + std::ptrdiff_t(this->data_offset()) + end_offset + 1, l); + return strided_data_end(*this, begin + std::ptrdiff_t(this->data_offset()), l, offset); } template @@ -522,15 +521,15 @@ namespace xt } template - inline auto xstrided_view::data_xend(layout_type l) noexcept -> container_iterator + inline auto xstrided_view::data_xend(layout_type l, size_type offset) noexcept -> container_iterator { - return data_xend_impl(this->storage().begin(), l); + return data_xend_impl(this->storage().begin(), l, offset); } template - inline auto xstrided_view::data_xend(layout_type l) const noexcept -> const_container_iterator + inline auto xstrided_view::data_xend(layout_type l, size_type offset) const noexcept -> const_container_iterator { - return data_xend_impl(this->storage().cbegin(), l); + return data_xend_impl(this->storage().cbegin(), l, offset); } template diff --git a/include/xtensor/xstrides.hpp b/include/xtensor/xstrides.hpp index 5ff82bca5..17cce17be 100644 --- a/include/xtensor/xstrides.hpp +++ b/include/xtensor/xstrides.hpp @@ -87,19 +87,33 @@ namespace xt * utility functions for strided containers * ********************************************/ - template - It strided_data_end(const C& c, It end, layout_type l) + template + It strided_data_end(const C& c, It begin, layout_type l, size_type offset) { using difference_type = typename std::iterator_traits::difference_type; if (c.dimension() == 0) { - return end; + ++begin; } else { - auto leading_stride = (l == layout_type::row_major ? c.strides().back() : c.strides().front()); - return end + difference_type(leading_stride - 1); + for (std::size_t i = 0; i != c.dimension(); ++i) + { + begin += c.strides()[i] * difference_type(c.shape()[i] - 1); + } + if (l == layout_type::row_major) + { + begin += c.strides().back(); + } + else + { + if (offset == 0) + { + begin += c.strides().front(); + } + } } + return begin; } /****************** @@ -279,7 +293,7 @@ namespace xt inline std::size_t compute_strides(const shape_type& shape, layout_type l, strides_type& strides, bs_ptr bs) { - using strides_value_type = std::decay_t; + using strides_value_type = typename std::decay_t::value_type; strides_value_type data_size = 1; if (L == layout_type::row_major || l == layout_type::row_major) { @@ -416,8 +430,9 @@ namespace xt template inline get_strides_t unravel_index(typename S::value_type index, const S& shape, layout_type l) { - get_strides_t strides = xtl::make_sequence>(shape.size(), 0); - using strides_value_type = std::decay_t; + using strides_type = get_strides_t; + using strides_value_type = typename strides_type::value_type; + strides_type strides = xtl::make_sequence(shape.size(), 0); compute_strides(shape, l, strides); return unravel_from_strides(static_cast(index), strides, l); } diff --git a/include/xtensor/xview.hpp b/include/xtensor/xview.hpp index 8cf3bc73e..5bd4bf25d 100644 --- a/include/xtensor/xview.hpp +++ b/include/xtensor/xview.hpp @@ -537,12 +537,12 @@ namespace xt inline It data_xbegin_impl(It begin) const noexcept; template - inline It data_xend_impl(It begin, layout_type l) const noexcept; + inline It data_xend_impl(It begin, layout_type l, size_type offset) const noexcept; inline container_iterator data_xbegin() noexcept; inline const_container_iterator data_xbegin() const noexcept; - inline container_iterator data_xend(layout_type l) noexcept; + inline container_iterator data_xend(layout_type l, size_type offset) noexcept; - inline const_container_iterator data_xend(layout_type l) const noexcept; + inline const_container_iterator data_xend(layout_type l, size_type offset) const noexcept; // Conversion operator enabled for statically "scalar" views template >::value, int>> @@ -1377,10 +1377,9 @@ namespace xt template template - inline It xview::data_xend_impl(It begin, layout_type l) const noexcept + inline It xview::data_xend_impl(It begin, layout_type l, size_type offset) const noexcept { - std::ptrdiff_t end_offset = static_cast(std::accumulate(backstrides().begin(), backstrides().end(), std::size_t(0))); - return strided_data_end(*this, begin + end_offset + 1, l); + return strided_data_end(*this, begin, l, offset); } template @@ -1396,15 +1395,15 @@ namespace xt } template - inline auto xview::data_xend(layout_type l) noexcept -> container_iterator + inline auto xview::data_xend(layout_type l, size_type offset) noexcept -> container_iterator { - return data_xend_impl(data() + data_offset(), l); + return data_xend_impl(data() + data_offset(), l, offset); } template - inline auto xview::data_xend(layout_type l) const noexcept -> const_container_iterator + inline auto xview::data_xend(layout_type l, size_type offset) const noexcept -> const_container_iterator { - return data_xend_impl(data() + data_offset(), l); + return data_xend_impl(data() + data_offset(), l, offset); } // Assign to operator enabled for contigous views @@ -1779,7 +1778,7 @@ namespace xt inline auto xview::stepper_end(const ST& shape, layout_type l) -> std::enable_if_t { size_type offset = shape.size() - dimension(); - return stepper(this, data_xend(l), offset); + return stepper(this, data_xend(l, offset), offset); } template @@ -1795,7 +1794,7 @@ namespace xt inline auto xview::stepper_end(const ST& shape, layout_type l) const-> std::enable_if_t { size_type offset = shape.size() - dimension(); - return const_stepper(this, data_xend(l), offset); + return const_stepper(this, data_xend(l, offset), offset); } /******************************** From e28132c76ccc4bccbbce9b7c3483c86a188a1c64 Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Tue, 13 Nov 2018 13:47:01 +0100 Subject: [PATCH 0004/1112] Moving VS2017 to allowed failure --- .appveyor.yml | 14 ++++++++------ .travis.yml | 4 +--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 5e2ac542a..1da0e5ebe 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -5,8 +5,12 @@ platform: - x86 image: - - Previous Visual Studio 2017 - Visual Studio 2015 + - Visual Studio 2017 + +matrix: + allow_failures: + - image: Visual Studio 2017 environment: matrix: @@ -16,8 +20,8 @@ init: - "ECHO %MINICONDA%" - if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2015" set VCVARPATH="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" - if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2015" set VCARGUMENT=%PLATFORM% - - if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Previous Visual Studio 2017" if "%PLATFORM%" == "x64" set VCVARPATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" - - if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Previous Visual Studio 2017" if "%PLATFORM%" == "x86" set VCVARPATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" + - if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" if "%PLATFORM%" == "x64" set VCVARPATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" + - if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2017" if "%PLATFORM%" == "x86" set VCVARPATH="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" - echo "%VCVARPATH% %VCARGUMENT%" - "%VCVARPATH% %VCARGUMENT%" - ps: if($env:Platform -eq "x64"){Start-FileDownload 'http://repo.continuum.io/miniconda/Miniconda3-latest-Windows-x86_64.exe' C:\Miniconda.exe; echo "Done"} @@ -30,9 +34,7 @@ install: - conda update -q conda - conda info -a - conda install gtest=1.8.0 cmake -c conda-forge - - conda install xtl==0.4.16 -c QuantStack - - conda install xsimd -c QuantStack - - conda install nlohmann_json -c QuantStack + - conda install xtl==0.4.16 xsimd nlohmann_json -c QuantStack #- cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\LIBRARY -DBUILD_TESTS=ON -DXTENSOR_USE_XSIMD=ON -DDISABLE_VS2017=ON . #- cmake -G "NMake Makefiles" -D CMAKE_INSTALL_PREFIX=%MINICONDA%\\LIBRARY -DBUILD_TESTS=ON -DDISABLE_VS2017=ON . #- if "%APPVEYOR_BUILD_WORKER_IMAGE%" == "Visual Studio 2015" if "%PLATFORM%" == "x64" cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=%MINICONDA%\\LIBRARY -DBUILD_TESTS=ON -DXTENSOR_USE_XSIMD=ON . diff --git a/.travis.yml b/.travis.yml index a11787c40..2e8bd34e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -127,9 +127,7 @@ install: - conda config --set always_yes yes --set changeps1 no - conda update -q conda - conda install gtest=1.8.0 cmake -c conda-forge - - conda install xtl==0.4.16 -c QuantStack - - conda install xsimd -c QuantStack - - conda install nlohmann_json -c QuantStack + - conda install xtl==0.4.16 xsimd nlohmann_json -c QuantStack - if [[ "$ENABLE_TBB" == 1 ]]; then conda install tbb-devel -c conda-forge; fi From 19e55df933260536ff854828dc42f49889adcc55 Mon Sep 17 00:00:00 2001 From: Tom de Geus Date: Tue, 13 Nov 2018 15:52:49 +0100 Subject: [PATCH 0005/1112] Added default layout-type --- include/xtensor/xstrides.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/xtensor/xstrides.hpp b/include/xtensor/xstrides.hpp index 5ff82bca5..a4dff3939 100644 --- a/include/xtensor/xstrides.hpp +++ b/include/xtensor/xstrides.hpp @@ -61,10 +61,10 @@ namespace xt *****************/ template - S unravel_from_strides(typename S::value_type index, const S& strides, layout_type l); + S unravel_from_strides(typename S::value_type index, const S& strides, layout_type l=layout_type::row_major); template - get_strides_t unravel_index(typename S::value_type index, const S& shape, layout_type l); + get_strides_t unravel_index(typename S::value_type index, const S& shape, layout_type l=layout_type::row_major); /*********************** * broadcast functions * From e572e9368bdd73164d3826921e7b54402d4aa915 Mon Sep 17 00:00:00 2001 From: Sylvain Corlay Date: Tue, 13 Nov 2018 17:28:01 +0100 Subject: [PATCH 0006/1112] WIP Xfunction iterator fix (#1241) Xfunction iterator fix --- include/xtensor/xbuilder.hpp | 12 +++--- include/xtensor/xfunction.hpp | 6 ++- include/xtensor/xscalar.hpp | 4 +- include/xtensor/xstrided_view.hpp | 28 +------------ include/xtensor/xtensor_forward.hpp | 31 +++++++++++++++ test/test_xfunction.cpp | 62 +++++++++++++++++++++++++++++ 6 files changed, 106 insertions(+), 37 deletions(-) diff --git a/include/xtensor/xbuilder.hpp b/include/xtensor/xbuilder.hpp index c58663c03..78dfe2796 100644 --- a/include/xtensor/xbuilder.hpp +++ b/include/xtensor/xbuilder.hpp @@ -136,9 +136,9 @@ namespace xt * @param e the xexpression from which to extract shape, value type and layout. */ template - inline typename E::temporary_type empty_like(const xexpression& e) + inline auto empty_like(const xexpression& e) { - using xtype = typename E::temporary_type; + using xtype = detail::temporary_type_t; auto res = xtype::from_shape(e.derived_cast().shape()); return res; } @@ -151,9 +151,9 @@ namespace xt * @param fill_value the value used to set each element of the returned xcontainer. */ template - inline typename E::temporary_type full_like(const xexpression& e, typename E::value_type fill_value) + inline auto full_like(const xexpression& e, typename E::value_type fill_value) { - using xtype = typename E::temporary_type; + using xtype = detail::temporary_type_t; auto res = xtype::from_shape(e.derived_cast().shape()); res.fill(fill_value); return res; @@ -169,7 +169,7 @@ namespace xt * @param e the xexpression from which to extract shape, value type and layout. */ template - inline typename E::temporary_type zeros_like(const xexpression& e) + inline auto zeros_like(const xexpression& e) { return full_like(e, typename E::value_type(0)); } @@ -184,7 +184,7 @@ namespace xt * @param e the xexpression from which to extract shape, value type and layout. */ template - inline typename E::temporary_type ones_like(const xexpression& e) + inline auto ones_like(const xexpression& e) { return full_like(e, typename E::value_type(1)); } diff --git a/include/xtensor/xfunction.hpp b/include/xtensor/xfunction.hpp index 033b29a73..8d04ac274 100644 --- a/include/xtensor/xfunction.hpp +++ b/include/xtensor/xfunction.hpp @@ -1025,7 +1025,8 @@ namespace xt { // Optimization: no need to compare each subiterator since they all // are incremented decremented together. - constexpr std::size_t index = xtl::mpl::find_if::value; + constexpr std::size_t temp = xtl::mpl::find_if::value; + constexpr std::size_t index = (temp == std::tuple_size::value) ? 0 : temp; return std::get(m_it) == std::get(rhs.m_it); } @@ -1034,7 +1035,8 @@ namespace xt { // Optimization: no need to compare each subiterator since they all // are incremented decremented together. - constexpr std::size_t index = xtl::mpl::find_if::value; + constexpr std::size_t temp = xtl::mpl::find_if::value; + constexpr std::size_t index = (temp == std::tuple_size::value) ? 0 : temp; return std::get(m_it) < std::get(rhs.m_it); } diff --git a/include/xtensor/xscalar.hpp b/include/xtensor/xscalar.hpp index 6002b9a34..ecd37b6f5 100644 --- a/include/xtensor/xscalar.hpp +++ b/include/xtensor/xscalar.hpp @@ -444,12 +444,12 @@ namespace xt const xdummy_iterator& rhs) noexcept; template - struct is_xdummy_iterator : std::false_type + struct is_not_xdummy_iterator : std::true_type { }; template - struct is_xdummy_iterator> : std::true_type + struct is_not_xdummy_iterator> : std::false_type { }; diff --git a/include/xtensor/xstrided_view.hpp b/include/xtensor/xstrided_view.hpp index 0746ef92d..174a3933a 100644 --- a/include/xtensor/xstrided_view.hpp +++ b/include/xtensor/xstrided_view.hpp @@ -24,6 +24,7 @@ #include "xsemantic.hpp" #include "xstorage.hpp" #include "xstrided_view_base.hpp" +#include "xutils.hpp" namespace xt { @@ -52,33 +53,6 @@ namespace xt using xstrided_view_base_t = typename xstrided_view_base::type; } - namespace detail - { - template - struct xtype_for_shape - { - template - using type = xarray; - }; - - template