1 | /* |
2 | * aggregate_copy.hpp |
3 | * |
4 | * Created on: Oct 31, 2015 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #ifndef OPENFPM_DATA_SRC_UTIL_COPY_GENERAL_HPP_ |
9 | #define OPENFPM_DATA_SRC_UTIL_COPY_GENERAL_HPP_ |
10 | |
11 | #include "util/common.hpp" |
12 | #include "util/util_debug.hpp" |
13 | #include "copy_compare_aggregates.hpp" |
14 | #include "util/for_each_ref.hpp" |
15 | #include <boost/mpl/range_c.hpp> |
16 | #include <iostream> |
17 | #include "util/cuda_util.hpp" |
18 | #include "data_type/aggregate.hpp" |
19 | |
20 | /*! \brief This structure define the operation add to use with copy general |
21 | * |
22 | * \tparam Tdst destination object type |
23 | * \tparam Tsrc source object type |
24 | * |
25 | */ |
26 | template<typename Tdst, typename Tsrc> |
27 | struct max_ |
28 | { |
29 | /*! \brief Defition of the add operation |
30 | * |
31 | * \param dst Destination object |
32 | * \param src Source object |
33 | * |
34 | */ |
35 | static inline void operation(Tdst & dst, const Tsrc & src) |
36 | { |
37 | dst = (src > dst)?src:dst; |
38 | } |
39 | }; |
40 | |
41 | /*! \brief This structure define the operation add to use with copy general |
42 | * |
43 | * \tparam Tdst destination object type |
44 | * \tparam Tsrc source object type |
45 | * |
46 | */ |
47 | template<typename Tdst, typename Tsrc> |
48 | struct min_ |
49 | { |
50 | /*! \brief Defition of the add operation |
51 | * |
52 | * \param dst Destination object |
53 | * \param src Source object |
54 | * |
55 | */ |
56 | static inline void operation(Tdst & dst, const Tsrc & src) |
57 | { |
58 | dst = (src < dst)?src:dst; |
59 | } |
60 | }; |
61 | |
62 | /*! \brief This structure define the operation add to use with copy general |
63 | * |
64 | * \tparam Tdst destination object type |
65 | * \tparam Tsrc source object type |
66 | * |
67 | */ |
68 | template<typename Tdst, typename Tsrc> |
69 | struct add_ |
70 | { |
71 | /*! \brief Defition of the add operation |
72 | * |
73 | * \param dst Destination object |
74 | * \param src Source object |
75 | * |
76 | */ |
77 | __device__ __host__ static inline void operation(Tdst & dst, const Tsrc & src) |
78 | { |
79 | dst += src; |
80 | } |
81 | }; |
82 | |
83 | #ifdef __clang__ |
84 | template<typename Tsrc> |
85 | __host__ Tsrc atomicAdd(Tsrc * ptr, Tsrc value) |
86 | { |
87 | std::cout << __FILE__ << ":" << __LINE__ << "Error: atomicAdd is supported only in device code not host" << std::endl; |
88 | return 0; |
89 | } |
90 | #endif |
91 | |
92 | /*! \brief This structure define the operation add to use with copy general |
93 | * |
94 | * \tparam Tdst destination object type |
95 | * \tparam Tsrc source object type |
96 | * |
97 | */ |
98 | template<typename Tdst, typename Tsrc> |
99 | struct add_atomic_ |
100 | { |
101 | /*! \brief Defition of the add operation |
102 | * |
103 | * \param dst Destination object |
104 | * \param src Source object |
105 | * |
106 | */ |
107 | __device__ __host__ static inline void operation(Tdst & dst, const Tsrc & src) |
108 | { |
109 | atomicAdd(&dst,src); |
110 | } |
111 | }; |
112 | |
113 | /*! \brief This structure define the operation add to use with copy general |
114 | * |
115 | * \tparam Tdst destination object type |
116 | * \tparam Tsrc source object type |
117 | * |
118 | */ |
119 | template<typename Tdst, typename Tsrc> |
120 | struct replace_ |
121 | { |
122 | /*! \brief Defition of the replace operation |
123 | * |
124 | * \param dst Destination object |
125 | * \param src Source object |
126 | * |
127 | */ |
128 | static inline void operation(Tdst & dst, const Tsrc & src) |
129 | { |
130 | dst = src; |
131 | } |
132 | }; |
133 | |
134 | /*! \brief This structure define the operation add to use with copy general |
135 | * |
136 | * \tparam Tdst destination object type |
137 | * \tparam Tsrc source object type |
138 | * |
139 | */ |
140 | template<typename Tdst, typename Tsrc> |
141 | struct merge_ |
142 | { |
143 | /*! \brief Defition of the add operation |
144 | * |
145 | * \param dst Destination object |
146 | * \param src Source object |
147 | * |
148 | */ |
149 | static inline void operation(Tdst & dst, const Tsrc & src) |
150 | { |
151 | dst.add(src); |
152 | } |
153 | }; |
154 | |
155 | /*! \brief structure to copy aggregates |
156 | * |
157 | * \tparam T type to copy |
158 | * |
159 | */ |
160 | template<typename T, unsigned int agg=2 * is_aggregate<T>::value + std::is_copy_assignable<T>::value> |
161 | struct copy_general |
162 | { |
163 | /*! \brief Specialization when there is unknown copy method |
164 | * |
165 | * \param src source object to copy |
166 | * \param dst destination object |
167 | * |
168 | */ |
169 | inline copy_general(const T & src, T & dst) |
170 | { |
171 | #ifndef DISABLE_ALL_RTTI |
172 | std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " " << demangle(typeid(T).name()) << " does not have an operator= and is not an aggregate or an openfpm native structure, copy is not possible" << "\n" ; |
173 | #endif |
174 | } |
175 | }; |
176 | |
177 | //! Specialization for if dst type is copy assignable from src type |
178 | template<typename T> |
179 | struct copy_general<T,1> |
180 | { |
181 | /*! \brief copy objects that has an operator= (implicit or explicit) |
182 | * |
183 | * \param src source object to copy |
184 | * \param dst destination object |
185 | * |
186 | */ |
187 | __device__ __host__ inline copy_general(const T & src, T & dst) |
188 | { |
189 | dst = src; |
190 | } |
191 | }; |
192 | |
193 | //! Specialization for aggregate type object |
194 | template<typename T> |
195 | struct copy_general<T,2> |
196 | { |
197 | /*! \brief copy objects that are aggregates |
198 | * |
199 | * \param src source object to copy |
200 | * \param dst destination object |
201 | * |
202 | */ |
203 | inline copy_general(const T & src, T & dst) |
204 | { |
205 | copy_aggregate<T> cp(src,dst); |
206 | |
207 | boost::mpl::for_each_ref<boost::mpl::range_c<int,0,T::max_prop>>(cp); |
208 | } |
209 | }; |
210 | |
211 | //! Specialization for aggregate type object that define an operator= |
212 | template<typename T> |
213 | struct copy_general<T,3> |
214 | { |
215 | /*! \brief copy objects that are aggregates but define an operator= |
216 | * |
217 | * \param src source object to copy |
218 | * \param dst destination object |
219 | * |
220 | */ |
221 | inline copy_general(const T & src, T & dst) |
222 | { |
223 | dst = src; |
224 | } |
225 | }; |
226 | |
227 | /////////////////// VERSION WITH OPERATIONS /////////////////// |
228 | |
229 | /*! \brief structure to copy aggregates applying an operation |
230 | * |
231 | * \tparam T type to copy |
232 | * |
233 | */ |
234 | template<template<typename,typename> class op, typename T, unsigned int agg=2 * is_aggregate<T>::value + std::is_copy_assignable<T>::value> |
235 | struct copy_general_op |
236 | { |
237 | /*! \brief Specialization when there is unknown copy method |
238 | * |
239 | * \param src source object to copy |
240 | * \param dst destination object |
241 | * |
242 | */ |
243 | inline copy_general_op(const T & src, T & dst) |
244 | { |
245 | #ifndef DISABLE_ALL_RTTI |
246 | std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " " << demangle(typeid(T).name()) << " does not have an operator " << demangle(typeid(op<T,T>).name()) << "defined" << std::endl; |
247 | #endif |
248 | } |
249 | }; |
250 | |
251 | //! Specialization for object that can be assigned with an operator copy |
252 | template<template<typename,typename> class op,typename T> |
253 | struct copy_general_op<op,T,1> |
254 | { |
255 | /*! \brief copy objects that has an operator= (implicit or explicit) |
256 | * |
257 | * \param src source object to copy |
258 | * \param dst destination object |
259 | * |
260 | */ |
261 | __device__ __host__ inline copy_general_op(const T & src, T & dst) |
262 | { |
263 | op<T,T>::operation(dst,src); |
264 | } |
265 | }; |
266 | |
267 | //! Specialization for aggregate type objects |
268 | template<template<typename,typename> class op, typename T> |
269 | struct copy_general_op<op,T,3> |
270 | { |
271 | /*! \brief copy objects that are aggregates |
272 | * |
273 | * \param src source object to copy |
274 | * \param dst destination object |
275 | * |
276 | */ |
277 | __device__ __host__ inline copy_general_op(const T & src, T & dst) |
278 | { |
279 | copy_aggregate_op<op,T> cp(src,dst); |
280 | |
281 | boost::mpl::for_each_ref<boost::mpl::range_c<int,0,T::max_prop>>(cp); |
282 | } |
283 | }; |
284 | |
285 | |
286 | #endif /* OPENFPM_DATA_SRC_UTIL_COPY_GENERAL_HPP_ */ |
287 | |