xtensor
Loading...
Searching...
No Matches
xchunked_view.hpp
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_CHUNKED_VIEW_HPP
11#define XTENSOR_CHUNKED_VIEW_HPP
12
13#include <xtl/xsequence.hpp>
14
15#include "xchunked_array.hpp"
16#include "xnoalias.hpp"
17#include "xstorage.hpp"
18#include "xstrided_view.hpp"
19
20namespace xt
21{
22
23 template <class E>
24 struct is_chunked_t : detail::chunk_helper<E>::is_chunked
25 {
26 };
27
28 /*****************
29 * xchunked_view *
30 *****************/
31
32 template <class E>
33 class xchunk_iterator;
34
35 template <class E>
37 {
38 public:
39
41 using expression_type = std::decay_t<E>;
42 using value_type = typename expression_type::value_type;
43 using reference = typename expression_type::reference;
44 using const_reference = typename expression_type::const_reference;
45 using pointer = typename expression_type::pointer;
46 using const_pointer = typename expression_type::const_pointer;
47 using size_type = typename expression_type::size_type;
48 using difference_type = typename expression_type::difference_type;
52
53 template <class OE, class S>
54 xchunked_view(OE&& e, S&& chunk_shape);
55
56 template <class OE>
58
59 void init();
60
61 template <class OE>
62 typename std::enable_if_t<!is_chunked_t<OE>::value, xchunked_view<E>&> operator=(const OE& e);
63
64 template <class OE>
65 typename std::enable_if_t<is_chunked_t<OE>::value, xchunked_view<E>&> operator=(const OE& e);
66
67 size_type dimension() const noexcept;
68 const shape_type& shape() const noexcept;
69 const shape_type& chunk_shape() const noexcept;
70 size_type grid_size() const noexcept;
71 const shape_type& grid_shape() const noexcept;
72
73 expression_type& expression() noexcept;
74 const expression_type& expression() const noexcept;
75
76 chunk_iterator chunk_begin();
77 chunk_iterator chunk_end();
78
79 const_chunk_iterator chunk_begin() const;
80 const_chunk_iterator chunk_end() const;
81 const_chunk_iterator chunk_cbegin() const;
82 const_chunk_iterator chunk_cend() const;
83
84 private:
85
86 E m_expression;
87 shape_type m_shape;
88 shape_type m_chunk_shape;
89 shape_type m_grid_shape;
90 size_type m_chunk_nb;
91 };
92
93 template <class E, class S>
94 xchunked_view<E> as_chunked(E&& e, S&& chunk_shape);
95
96 /********************************
97 * xchunked_view implementation *
98 ********************************/
99
100 template <class E>
101 template <class OE, class S>
102 inline xchunked_view<E>::xchunked_view(OE&& e, S&& chunk_shape)
103 : m_expression(std::forward<OE>(e))
104 , m_chunk_shape(xtl::forward_sequence<shape_type, S>(chunk_shape))
105 {
106 m_shape.resize(e.dimension());
107 const auto& s = e.shape();
108 std::copy(s.cbegin(), s.cend(), m_shape.begin());
109 init();
110 }
111
112 template <class E>
113 template <class OE>
114 inline xchunked_view<E>::xchunked_view(OE&& e)
115 : m_expression(std::forward<OE>(e))
116 {
117 m_shape.resize(e.dimension());
118 const auto& s = e.shape();
119 std::copy(s.cbegin(), s.cend(), m_shape.begin());
120 }
121
122 template <class E>
123 void xchunked_view<E>::init()
124 {
125 // compute chunk number in each dimension
126 m_grid_shape.resize(m_shape.size());
127 std::transform(
128 m_shape.cbegin(),
129 m_shape.cend(),
130 m_chunk_shape.cbegin(),
131 m_grid_shape.begin(),
132 [](auto s, auto cs)
133 {
134 std::size_t cn = s / cs;
135 if (s % cs > 0)
136 {
137 cn++; // edge_chunk
138 }
139 return cn;
140 }
141 );
142 m_chunk_nb = std::accumulate(
143 std::begin(m_grid_shape),
144 std::end(m_grid_shape),
145 std::size_t(1),
146 std::multiplies<>()
147 );
148 }
149
150 template <class E>
151 template <class OE>
152 typename std::enable_if_t<!is_chunked_t<OE>::value, xchunked_view<E>&>
153 xchunked_view<E>::operator=(const OE& e)
154 {
155 auto end = chunk_end();
156 for (auto it = chunk_begin(); it != end; ++it)
157 {
158 auto el = *it;
159 noalias(el) = strided_view(e, it.get_slice_vector());
160 }
161 return *this;
162 }
163
164 template <class E>
165 template <class OE>
166 typename std::enable_if_t<is_chunked_t<OE>::value, xchunked_view<E>&>
167 xchunked_view<E>::operator=(const OE& e)
168 {
169 m_chunk_shape.resize(e.dimension());
170 const auto& cs = e.chunk_shape();
171 std::copy(cs.cbegin(), cs.cend(), m_chunk_shape.begin());
172 init();
173 auto it2 = e.chunks().begin();
174 auto end1 = chunk_end();
175 for (auto it1 = chunk_begin(); it1 != end1; ++it1, ++it2)
176 {
177 auto el1 = *it1;
178 auto el2 = *it2;
179 auto lhs_shape = el1.shape();
180 if (lhs_shape != el2.shape())
181 {
182 xstrided_slice_vector esv(el2.dimension()); // element slice in edge chunk
183 std::transform(
184 lhs_shape.begin(),
185 lhs_shape.end(),
186 esv.begin(),
187 [](auto size)
188 {
189 return range(0, size);
190 }
191 );
192 noalias(el1) = strided_view(el2, esv);
193 }
194 else
195 {
196 noalias(el1) = el2;
197 }
198 }
199 return *this;
200 }
201
202 template <class E>
203 inline auto xchunked_view<E>::dimension() const noexcept -> size_type
204 {
205 return m_shape.size();
206 }
207
208 template <class E>
209 inline auto xchunked_view<E>::shape() const noexcept -> const shape_type&
210 {
211 return m_shape;
212 }
213
214 template <class E>
215 inline auto xchunked_view<E>::chunk_shape() const noexcept -> const shape_type&
216 {
217 return m_chunk_shape;
218 }
219
220 template <class E>
221 inline auto xchunked_view<E>::grid_size() const noexcept -> size_type
222 {
223 return m_chunk_nb;
224 }
225
226 template <class E>
227 inline auto xchunked_view<E>::grid_shape() const noexcept -> const shape_type&
228 {
229 return m_grid_shape;
230 }
231
232 template <class E>
233 inline auto xchunked_view<E>::expression() noexcept -> expression_type&
234 {
235 return m_expression;
236 }
237
238 template <class E>
239 inline auto xchunked_view<E>::expression() const noexcept -> const expression_type&
240 {
241 return m_expression;
242 }
243
244 template <class E>
245 inline auto xchunked_view<E>::chunk_begin() -> chunk_iterator
246 {
247 shape_type chunk_index(m_shape.size(), size_type(0));
248 return chunk_iterator(*this, std::move(chunk_index), 0u);
249 }
250
251 template <class E>
252 inline auto xchunked_view<E>::chunk_end() -> chunk_iterator
253 {
254 return chunk_iterator(*this, shape_type(grid_shape()), grid_size());
255 }
256
257 template <class E>
258 inline auto xchunked_view<E>::chunk_begin() const -> const_chunk_iterator
259 {
260 shape_type chunk_index(m_shape.size(), size_type(0));
261 return const_chunk_iterator(*this, std::move(chunk_index), 0u);
262 }
263
264 template <class E>
265 inline auto xchunked_view<E>::chunk_end() const -> const_chunk_iterator
266 {
267 return const_chunk_iterator(*this, shape_type(grid_shape()), grid_size());
268 }
269
270 template <class E>
271 inline auto xchunked_view<E>::chunk_cbegin() const -> const_chunk_iterator
272 {
273 return chunk_begin();
274 }
275
276 template <class E>
277 inline auto xchunked_view<E>::chunk_cend() const -> const_chunk_iterator
278 {
279 return chunk_end();
280 }
281
282 template <class E, class S>
283 inline xchunked_view<E> as_chunked(E&& e, S&& chunk_shape)
284 {
285 return xchunked_view<E>(std::forward<E>(e), std::forward<S>(chunk_shape));
286 }
287
288 template <class E>
289 inline xchunked_view<E> as_chunked(E&& e)
290 {
291 return xchunked_view<E>(std::forward<E>(e));
292 }
293}
294
295#endif
standard mathematical functions for xexpressions
std::vector< xstrided_slice< std::ptrdiff_t > > xstrided_slice_vector
vector of slices used to build a xstrided_view
auto strided_view(E &&e, S &&shape, X &&stride, std::size_t offset=0, layout_type layout=L) noexcept
Construct a strided view from an xexpression, shape, strides and offset.