Skip to content

Commit 8fb97e6

Browse files
committed
blockwise reducers intital implementation
cleanup cleanup cleanup cleanup cleanup cleanup cleanup added explicit this cleanup const correctness const correctness more inline fixed broken tests ... added p norms added p norms fixed test winfix win fix win fix
1 parent 2618d5a commit 8fb97e6

11 files changed

+1726
-43
lines changed

include/xtensor/xblockwise_reducer.hpp

Lines changed: 498 additions & 0 deletions
Large diffs are not rendered by default.

include/xtensor/xblockwise_reducer_functors.hpp

Lines changed: 587 additions & 0 deletions
Large diffs are not rendered by default.

include/xtensor/xchunked_assign.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ namespace xt
135135
struct xchunk_iterator_base
136136
: std::conditional_t<is_xchunked_array<std::decay_t<T>>::value,
137137
xchunk_iterator_array<T>,
138-
std::conditional_t<is_xchunked_view<T>::value,
138+
std::conditional_t<is_xchunked_view<std::decay_t<T>>::value,
139139
xchunk_iterator_view<T>,
140140
invalid_chunk_iterator>>
141141
{
@@ -172,6 +172,8 @@ namespace xt
172172
bool operator==(const self_type& rhs) const;
173173
bool operator!=(const self_type& rhs) const;
174174

175+
const shape_type& chunk_index() const;
176+
175177
const slice_vector& get_slice_vector() const;
176178
slice_vector get_chunk_slice_vector() const;
177179

@@ -338,6 +340,12 @@ namespace xt
338340
{
339341
return m_slice_vector;
340342
}
343+
344+
template <class E>
345+
auto xchunk_iterator<E>::chunk_index() const -> const shape_type&
346+
{
347+
return m_chunk_index;
348+
}
341349

342350
template <class E>
343351
inline auto xchunk_iterator<E>::get_chunk_slice_vector() const -> slice_vector

include/xtensor/xgrid_iterator.hpp

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/***************************************************************************
2+
* Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
3+
* Copyright (c) QuantStack *
4+
* *
5+
* Distributed under the terms of the BSD 3-Clause License. *
6+
* *
7+
* The full license is in the file LICENSE, distributed with this software. *
8+
****************************************************************************/
9+
10+
#ifndef XTENSOR_XGRID_ITERATOR
11+
#define XTENSOR_XGRID_ITERATOR
12+
13+
#include "xtl/xsequence.hpp"
14+
15+
16+
#include "xstrided_view.hpp"
17+
18+
namespace xt
19+
{
20+
21+
template<class S>
22+
class xsubgrid_iterator
23+
{
24+
public:
25+
using self_type = xsubgrid_iterator<S>;
26+
using shape_type = S;
27+
28+
using value_type = shape_type;
29+
using reference = value_type &;
30+
using pointer = value_type*;
31+
using difference_type = std::size_t;
32+
using iterator_category = std::forward_iterator_tag;
33+
34+
xsubgrid_iterator() = default;
35+
xsubgrid_iterator(const xsubgrid_iterator&) = default;
36+
xsubgrid_iterator(xsubgrid_iterator&&) = default;
37+
xsubgrid_iterator& operator=(const xsubgrid_iterator&) = default;
38+
xsubgrid_iterator& operator=(xsubgrid_iterator&&) = default;
39+
40+
template<class B, class E, class C>
41+
xsubgrid_iterator(B && begin, E && end, C && current, const std::size_t linear_index)
42+
: m_begin(std::forward<B>(begin)),
43+
m_end(std::forward<E>(end)),
44+
m_current(std::forward<C>(current)),
45+
m_linear_index(linear_index)
46+
{
47+
48+
}
49+
50+
self_type& operator++()
51+
{
52+
std::size_t i = m_begin.size();
53+
while (i != 0)
54+
{
55+
--i;
56+
if (m_current[i] + 1u == m_end[i])
57+
{
58+
m_current[i] = m_begin[i];
59+
}
60+
else
61+
{
62+
m_current[i] += 1;
63+
break;
64+
}
65+
}
66+
m_linear_index++;
67+
return *this;
68+
}
69+
70+
self_type operator++(int)
71+
{
72+
self_type it = *this;
73+
++(*this);
74+
return it;
75+
}
76+
shape_type & operator*()
77+
{
78+
return m_current;
79+
}
80+
const shape_type & operator*() const
81+
{
82+
return m_current;
83+
}
84+
85+
bool operator==(const self_type& rhs) const
86+
{
87+
return m_linear_index == rhs.m_linear_index;
88+
}
89+
bool operator!=(const self_type& rhs) const
90+
{
91+
return !this->operator==(rhs);
92+
}
93+
94+
private:
95+
shape_type m_begin;
96+
shape_type m_end;
97+
shape_type m_current;
98+
std::size_t m_linear_index{0};
99+
};
100+
101+
102+
template<class S, class B, class E>
103+
auto subgrid_iterator_begin(B && roi_begin, E && roi_end)
104+
{
105+
S current;
106+
resize_container(current, roi_begin.size());
107+
std::copy(roi_begin.begin(), roi_begin.end(), current.begin());
108+
return xsubgrid_iterator<S>(
109+
std::forward<B>(roi_begin),
110+
std::forward<E>(roi_end),
111+
std::move(current),
112+
0
113+
);
114+
}
115+
116+
template<class S, class B, class E>
117+
auto subgrid_iterator_end(B && roi_begin, E && roi_end)
118+
{
119+
S current;
120+
resize_container(current, roi_begin.size());
121+
std::copy(roi_end.begin(), roi_end.end(), current.begin());
122+
123+
std::size_t linear_index = 1;
124+
for(std::size_t i=0; i<roi_begin.size(); ++i)
125+
{
126+
linear_index *= roi_end[i] - roi_begin[i];
127+
}
128+
129+
return xsubgrid_iterator<S>(
130+
std::forward<B>(roi_begin),
131+
std::forward<E>(roi_end),
132+
std::move(current),
133+
linear_index
134+
);
135+
}
136+
137+
}
138+
139+
#endif

include/xtensor/xmath.hpp

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -365,46 +365,46 @@ namespace detail {
365365
}
366366
}
367367

368-
#define XTENSOR_REDUCER_FUNCTION(NAME, FUNCTOR, INIT_VALUE_TYPE, INIT) \
369-
template <class T = void, class E, class X, class EVS = DEFAULT_STRATEGY_REDUCERS, \
370-
XTL_REQUIRES(xtl::negation<is_reducer_options<X>>, xtl::negation<xtl::is_integral<X>>)> \
371-
inline auto NAME(E&& e, X&& axes, EVS es = EVS()) \
372-
{ \
373-
using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>; \
374-
using functor_type = FUNCTOR; \
375-
using init_value_fct = xt::const_value<init_value_type>; \
376-
return xt::reduce(make_xreducer_functor(functor_type(), \
377-
init_value_fct(detail::fill_init<init_value_type>(INIT))), \
378-
std::forward<E>(e), \
379-
std::forward<X>(axes), es); \
380-
} \
381-
\
382-
template <class T = void, class E, class X, class EVS = DEFAULT_STRATEGY_REDUCERS, \
383-
XTL_REQUIRES(xtl::negation<is_reducer_options<X>>, xtl::is_integral<X>)> \
384-
inline auto NAME(E&& e, X axis, EVS es = EVS()) \
385-
{ \
386-
return NAME(std::forward<E>(e), {axis}, es); \
387-
} \
388-
\
389-
template <class T = void, class E, class EVS = DEFAULT_STRATEGY_REDUCERS, \
390-
XTL_REQUIRES(is_reducer_options<EVS>)> \
391-
inline auto NAME(E&& e, EVS es = EVS()) \
392-
{ \
393-
using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>; \
394-
using functor_type = FUNCTOR; \
395-
using init_value_fct = xt::const_value<init_value_type >; \
396-
return xt::reduce(make_xreducer_functor(functor_type(), \
397-
init_value_fct(detail::fill_init<init_value_type >(INIT))), std::forward<E>(e), es); \
398-
} \
399-
\
400-
template <class T = void, class E, class I, std::size_t N, class EVS = DEFAULT_STRATEGY_REDUCERS> \
401-
inline auto NAME(E&& e, const I (&axes)[N], EVS es = EVS()) \
402-
{ \
403-
using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>; \
404-
using functor_type = FUNCTOR; \
405-
using init_value_fct = xt::const_value<init_value_type >; \
406-
return xt::reduce(make_xreducer_functor(functor_type(), \
407-
init_value_fct(detail::fill_init<init_value_type >(INIT))), std::forward<E>(e), axes, es); \
368+
#define XTENSOR_REDUCER_FUNCTION(NAME, FUNCTOR, INIT_VALUE_TYPE, INIT) \
369+
template <class T = void, class E, class X, class EVS = DEFAULT_STRATEGY_REDUCERS, \
370+
XTL_REQUIRES(xtl::negation<is_reducer_options<X>>, xtl::negation<xtl::is_integral<std::decay_t<X> >> )> \
371+
inline auto NAME(E&& e, X&& axes, EVS es = EVS()) \
372+
{ \
373+
using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>; \
374+
using functor_type = FUNCTOR; \
375+
using init_value_fct = xt::const_value<init_value_type>; \
376+
return xt::reduce(make_xreducer_functor(functor_type(), \
377+
init_value_fct(detail::fill_init<init_value_type>(INIT))), \
378+
std::forward<E>(e), \
379+
std::forward<X>(axes), es); \
380+
} \
381+
\
382+
template <class T = void, class E, class X, class EVS = DEFAULT_STRATEGY_REDUCERS, \
383+
XTL_REQUIRES(xtl::negation<is_reducer_options<X>>, xtl::is_integral<std::decay_t<X>>)> \
384+
inline auto NAME(E&& e, X axis, EVS es = EVS()) \
385+
{ \
386+
return NAME(std::forward<E>(e), {axis}, es); \
387+
} \
388+
\
389+
template <class T = void, class E, class EVS = DEFAULT_STRATEGY_REDUCERS, \
390+
XTL_REQUIRES(is_reducer_options<EVS>)> \
391+
inline auto NAME(E&& e, EVS es = EVS()) \
392+
{ \
393+
using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>; \
394+
using functor_type = FUNCTOR; \
395+
using init_value_fct = xt::const_value<init_value_type >; \
396+
return xt::reduce(make_xreducer_functor(functor_type(), \
397+
init_value_fct(detail::fill_init<init_value_type >(INIT))), std::forward<E>(e), es); \
398+
} \
399+
\
400+
template <class T = void, class E, class I, std::size_t N, class EVS = DEFAULT_STRATEGY_REDUCERS> \
401+
inline auto NAME(E&& e, const I (&axes)[N], EVS es = EVS()) \
402+
{ \
403+
using init_value_type = std::conditional_t<std::is_same<T, void>::value, INIT_VALUE_TYPE, T>; \
404+
using functor_type = FUNCTOR; \
405+
using init_value_fct = xt::const_value<init_value_type >; \
406+
return xt::reduce(make_xreducer_functor(functor_type(), \
407+
init_value_fct(detail::fill_init<init_value_type >(INIT))), std::forward<E>(e), axes, es); \
408408
}
409409

410410
/*******************

include/xtensor/xutils.hpp

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,74 @@ namespace xt
332332
}
333333

334334
/***********************************
335-
* resize_container implementation *
335+
* construct_container_with_size implementation *
336336
***********************************/
337+
namespace detail
338+
{
339+
340+
template<class C>
341+
struct construct_container_with_size_impl
342+
{
343+
static C op(typename C::size_type size)
344+
{
345+
C c;
346+
const bool success = resize_container(c, size);
347+
if(!success)
348+
{
349+
XTENSOR_THROW(std::runtime_error, "cannot resize container to given size");
350+
}
351+
c.resize(size);
352+
return c;
353+
}
354+
};
337355

356+
template <class T, class A>
357+
struct construct_container_with_size_impl<std::vector<T,A>>
358+
{
359+
using container_type = std::vector<T,A>;
360+
static container_type op(typename container_type::size_type size)
361+
{
362+
return container_type(size);
363+
}
364+
};
365+
366+
template <class T, std::size_t N>
367+
struct construct_container_with_size_impl<std::array<T, N>>
368+
{
369+
using container_type = std::array<T, N>;
370+
static container_type op(typename container_type::size_type size)
371+
{
372+
if(size != N)
373+
{
374+
XTENSOR_THROW(std::runtime_error, "cannot resize container to given size");
375+
}
376+
return container_type{};
377+
}
378+
};
379+
380+
template <std::size_t... I>
381+
struct construct_container_with_size_impl<xt::fixed_shape<I...>>
382+
{
383+
using container_type = xt::fixed_shape<I...>;
384+
static container_type op(std::size_t size)
385+
{
386+
if(sizeof...(I) != size)
387+
{
388+
XTENSOR_THROW(std::runtime_error, "cannot resize container to given size");
389+
}
390+
return container_type{};
391+
}
392+
};
393+
}
394+
395+
template <class C, class S>
396+
inline C construct_container_with_size(S size)
397+
{
398+
return detail::construct_container_with_size_impl<C>::op(size);
399+
}
400+
/***********************************
401+
* resize_container implementation *
402+
***********************************/
338403
template <class C>
339404
inline bool resize_container(C& c, typename C::size_type size)
340405
{

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ set(COMMON_BASE
133133
test_xadaptor_semantic.cpp
134134
test_xarray_adaptor.cpp
135135
test_xarray.cpp
136+
test_xblockwise_reducer.cpp
136137
test_xbroadcast.cpp
137138
test_xbuilder.cpp
138139
test_xcontainer_semantic.cpp
@@ -142,6 +143,7 @@ set(COMMON_BASE
142143
test_xexpression_traits.cpp
143144
test_xfunction.cpp
144145
test_xfunc_on_xexpression.cpp
146+
test_xgrid_iterator.cpp
145147
test_xiterator.cpp
146148
test_xmath.cpp
147149
test_xoperation.cpp

test/test_common.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010
#ifndef TEST_COMMON_HPP
1111
#define TEST_COMMON_HPP
1212

13+
#include <sstream>
14+
1315
#include "xtensor/xlayout.hpp"
1416
#include "xtensor/xmanipulation.hpp"
17+
#include "xtensor/xreducer.hpp" // tuple_idx_of
18+
1519
#include "test_common_macros.hpp"
1620

1721
// the tests used to be implemented with gtest
@@ -28,6 +32,28 @@ namespace testing
2832

2933
namespace xt
3034
{
35+
template<class C>
36+
std::string stringify(const C & container)
37+
{
38+
std::size_t i = 0;
39+
std::stringstream ss;
40+
ss << "[";
41+
for(auto && c : container)
42+
{
43+
if(i + 1 == container.size())
44+
{
45+
ss<<c;
46+
}
47+
else
48+
{
49+
ss<<c<<",";
50+
}
51+
++i;
52+
}
53+
ss << "]";
54+
return ss.str();
55+
}
56+
3157
template <class T, class A, class AV>
3258
bool operator==(const uvector<T, A>& lhs, const std::vector<T, AV>& rhs)
3359
{

0 commit comments

Comments
 (0)