OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
multi_array_ref_openfpm.hpp
1/*
2 * multi_array_ref_openfpm.hpp
3 *
4 * This is an heavily modified boost::multi_array version
5 *
6 * Created on: Jun 29, 2018
7 * Author: i-bird
8 */
9
10#ifndef MULTI_ARRAY_REF_OPENFPM_HPP_
11#define MULTI_ARRAY_REF_OPENFPM_HPP_
12
13#include "util/cuda_util.hpp"
14#include "boost/multi_array/collection_concept.hpp"
15#include "boost/multi_array/concept_checks.hpp"
16#include "boost/multi_array/algorithm.hpp"
17#include <boost/mpl/placeholders.hpp>
18#include <boost/mpl/accumulate.hpp>
19#include <boost/mpl/multiplies.hpp>
20#include <boost/concept_check.hpp>
21#include "array_openfpm.hpp"
22#include "types.hpp"
23#include "multi_array_ref_base_openfpm.hpp"
24#include "multi_array_ref_subarray_openfpm.hpp"
25#include "storage_order.hpp"
26#include "multi_array_iterator_openfpm.hpp"
27#include "util/common.hpp"
28
29namespace openfpm {
30
31
32
33template <typename T, std::size_t NumDims, typename vector, typename TPtr>
35{
37
38 typedef typename boost::mpl::accumulate<vector,
39 typename boost::mpl::int_<1>,
40 typename boost::mpl::multiplies<typename boost::mpl::_2,typename boost::mpl::_1> >::type size_ct;
41
42public:
43
44/* typedef typename super_type::value_type value_type;*/
45 typedef typename super_type::const_reference const_reference;
47/* typedef typename super_type::const_reverse_iterator const_reverse_iterator;*/
48 typedef T element;
49 typedef size_t size_type;
50/* typedef typename super_type::difference_type difference_type;*/
51 typedef typename super_type::index index;
52/* typedef typename super_type::extent_range extent_range;*/
54
55 template <typename ExtentType>
56 explicit const_multi_array_ref_openfpm(TPtr base, const ExtentType& extents, const general_storage_order<NumDims>& so)
57 :base_(base),storage_(so)
58 {
59 init_multi_array_ref(extents);
60 }
61
62
63 template <class InputIterator>
64 void assign(InputIterator begin, InputIterator end)
65 {
66 boost::function_requires<boost::InputIteratorConcept<InputIterator> >();
67
68 InputIterator in_iter = begin;
69 T* out_iter = base_;
70 std::size_t copy_count=0;
71 while (in_iter != end && copy_count < num_elements_)
72 {
73 *out_iter++ = *in_iter++;
74 copy_count++;
75 }
76 }
77
78 size_type num_dimensions() const { return NumDims; }
79
80 size_type size() const { return extent_sz; }
81
82 // given reshaping functionality, this is the max possible size.
83 size_type max_size() const { return num_elements(); }
84
85 bool empty() const { return size() == 0; }
86
87 inline __device__ __host__ const index* strides() const {return stride_list_.data();}
88 inline __device__ __host__ const element* origin() const { return base_; }
89 inline __device__ __host__ const element* data() const { return base_; }
90
91 size_type num_elements() const { return num_elements_; }
92
93 const_iterator begin() const
94 {
95 return const_iterator(0,origin(),size(),strides());
96 }
97
98 const_iterator end() const
99 {
100 return const_iterator(size(),origin(),size(),strides());
101 }
102
104
105 // This is used by multi_array, which is a subclass of this
106 void set_base_ptr(TPtr new_base) { base_ = new_base; }
107
108
109 TPtr base_;
110 storage_order_type storage_;
111 size_type extent_sz;
112 size_type num_elements_;
113 index_list stride_list_;
114
115private:
116
117 // const_multi_array_ref cannot be assigned to (no deep copies!)
119
120 void init_multi_array_ref(const index sz)
121 {
122 // calculate the extents
123 extent_sz = sz;
124
125 this->compute_strides(stride_list_,extent_sz,storage_);
126
127 num_elements_ = sz * size_ct::value;
128 }
129};
130
131
132template <typename T, int NumDims, typename vector>
133class multi_array_ref_openfpm : public const_multi_array_ref_openfpm<T,NumDims,vector,T *>
134{
136public:
137/* typedef typename super_type::value_type value_type;*/
138 typedef typename super_type::reference reference;
139 typedef typename super_type::iterator iterator;
140/* typedef typename super_type::reverse_iterator reverse_iterator;*/
141 typedef typename super_type::const_reference const_reference;
143/* typedef typename super_type::const_reverse_iterator const_reverse_iterator;*/
144 typedef typename super_type::element element;
145 typedef typename super_type::size_type size_type;
146// typedef typename super_type::difference_type difference_type;
147 typedef typename super_type::index index;
148/* typedef typename super_type::extent_range extent_range;*/
149
151 typedef typename super_type::index_list index_list;
152
155
156/* typedef typename super_type::size_list size_list;*/
157
158 template <class ExtentType>
159 explicit multi_array_ref_openfpm(T* base, const ExtentType r_sz, const general_storage_order<NumDims>& so)
160 :super_type(base,r_sz,so)
161 {
162 }
163
164 // Assignment from other ConstMultiArray types.
165 template <typename ConstMultiArray>
166 multi_array_ref_openfpm & operator=(const ConstMultiArray& other)
167 {
168 boost::function_requires<
169 boost::multi_array_concepts::
170 ConstMultiArrayConcept<ConstMultiArray,NumDims> >();
171
172 // make sure the dimensions agree
173 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
174 BOOST_ASSERT(std::equal(other.shape(),other.shape()+this->num_dimensions(),
175 this->shape()));
176 // iterator-based copy
177 std::copy(other.begin(),other.end(),this->begin());
178 return *this;
179 }
180
181 multi_array_ref_openfpm & operator=(const multi_array_ref_openfpm & other)
182 {
183 if (&other != this)
184 {
185 // make sure the dimensions agree
186
187 BOOST_ASSERT(other.num_dimensions() == this->num_dimensions());
188
189 // iterator-based copy
190 std::copy(other.begin(),other.end(),this->begin());
191 }
192 return *this;
193 }
194
195 multi_array_ref_openfpm & bind_ref(const multi_array_ref_openfpm & other)
196 {
197 if (&other != this) {
198
199 this->base_ = other.base_;
200 this->storage_ = other.storage_;
201 this->extent_sz = other.extent_sz;
202 this->stride_list_ = other.stride_list_;
203 this->num_elements_ = other.num_elements_;
204 }
205 return *this;
206 }
207
208 /* \brief Set the internal pointer
209 *
210 * \param base internal pointer
211 *
212 */
213 void set_pointer(void * base)
214 {
215 this->base_ = static_cast<T *>(base);
216 }
217
218 /* \brief Get the internal pointer
219 *
220 * \return the internal pointer
221 *
222 */
223 __device__ __host__ void * get_pointer()
224 {
225 return this->base_;
226 }
227
228 /* \brief Get the internal pointer
229 *
230 * \return the internal pointer
231 *
232 */
233 __device__ __host__ const void * get_pointer() const
234 {
235 return this->base_;
236 }
237
238 multi_array_ref_openfpm & operator=(multi_array_ref_openfpm && other)
239 {
240 swap(other);
241
242 return *this;
243 }
244
245 void swap(multi_array_ref_openfpm & other)
246 {
247 T* base_tmp = this->base_;
248 this->base_ = other.base_;
249 other.base_ = base_tmp;
250
251 storage_order_type storage_tmp = this->storage_;
252 this->storage_ = other.storage_;
253 other.storage_ = storage_tmp;
254
255 size_type extent_tmp = this->extent_sz;
256 this->extent_sz = other.extent_sz;
257 other.extent_sz = extent_tmp;
258
259 index_list stride_list_tmp = this->stride_list_;
260 this->stride_list_ = other.stride_list_;
261 other.stride_list_ = stride_list_tmp;
262
263 size_type num_elements_tmp = this->num_elements_;
264 this->num_elements_ = other.num_elements_;
265 other.num_elements_ = num_elements_tmp;
266 }
267
268 __device__ __host__ element* origin() { return super_type::base_; }
269
270 __device__ __host__ const element* origin() const { return super_type::origin(); }
271
272 __device__ __host__ reference operator[](index idx)
273 {
274 return super_type::access(boost::type<reference>(),
275 idx,
276 this->strides(),
277 this->origin());
278 }
279
280
281
282 iterator begin()
283 {return iterator(0,origin(),this->size(),this->strides());}
284
285 iterator end()
286 {return iterator(this->size(),origin(),this->size(),this->strides());}
287
288 __inline__ __device__ __host__ const_reference operator[](index idx) const
289 {
290 return super_type::access(boost::type<const_reference>(),
291 idx,
292 this->strides(),
293 this->origin());
294 }
295
296 const_iterator begin() const
297 {return super_type::begin();}
298
299 const_iterator end() const
300 {return super_type::end();}
301};
302
303template<typename T, typename Sfinae = void>
304struct is_multi_array: std::false_type {};
305
306
318template<typename T>
319struct is_multi_array<T, typename Void<typename T::yes_is_multi_array >::type> : std::true_type
320{};
321
322} // namespace openfpm
323
324
325#endif /* MULTI_ARRAY_REF_OPENFPM_HPP_ */
int yes_is_multi_array
indicate that this class is a multi dimensional array
Implementation of 1-D std::vector like structure.
convert a type into constant type
Void structure.
Definition common.hpp:74