OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
vector_dist_operators_functions.hpp
1/*
2 * vector_dist_operators_functions.hpp
3 *
4 * Created on: Jul 17, 2016
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_FUNCTIONS_HPP_
9#define OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_FUNCTIONS_HPP_
10
11#ifdef __NVCC__
12#include "cuda/vector_dist_operators_cuda.cuh"
13#endif
14
15
22#define CREATE_VDIST_ARG_FUNC(fun_base,fun_name,OP_ID) \
23\
24\
25template <typename exp1>\
26class vector_dist_expression_op<exp1,void,OP_ID>\
27{\
28 const exp1 o1;\
29\
30public:\
31\
32 typedef typename exp1::is_ker is_ker;\
33\
34 typedef typename vector_result<typename exp1::vtype,void>::type vtype;\
35\
36 typedef typename vector_is_sort_result<exp1::is_sort::value,false>::type is_sort;\
37\
38 typedef typename nn_type_result<typename exp1::NN_type,void>::type NN_type;\
39\
40 vector_dist_expression_op(const exp1 & o1)\
41 :o1(o1)\
42 {}\
43\
44 inline NN_type * getNN()\
45 {\
46 return nn_type_result<typename exp1::NN_type,void>::getNN(o1);\
47 }\
48\
49 const vtype & getVector()\
50 {\
51 return vector_result<typename exp1::vtype,void>::getVector(o1);\
52 }\
53\
54 inline const exp1 & getExpr() const\
55 {\
56 return o1;\
57 }\
58 \
59 inline void init() const\
60 {\
61 o1.init();\
62 }\
63\
64 template<typename r_type=typename std::remove_reference<decltype(fun_base(o1.value(vect_dist_key_dx(0))))>::type > \
65 __device__ __host__ inline r_type value(const vect_dist_key_dx & key) const\
66 {\
67 return fun_base(o1.value(key));\
68 }\
69\
70 template<typename r_type=typename std::remove_reference<decltype(fun_base(o1.value(vect_dist_key_dx(0))))>::type > \
71 __device__ __host__ inline r_type value(const unsigned int & key) const\
72 {\
73 return fun_base(o1.value(key));\
74 }\
75 \
76 const vtype & getVector() const\
77 {\
78 return o1.getVector();\
79 }\
80 \
81};\
82\
83\
84template<typename exp1, typename exp2_, unsigned int op1>\
85inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2_,op1>,void,OP_ID>\
86fun_name(const vector_dist_expression_op<exp1,exp2_,op1> & va)\
87{\
88 vector_dist_expression_op<vector_dist_expression_op<exp1,exp2_,op1>,void,OP_ID> exp_sum(va);\
89\
90 return exp_sum;\
91}\
92\
93\
94template<unsigned int prp1, typename v1>\
95inline vector_dist_expression_op<vector_dist_expression<prp1,v1>,void,OP_ID>\
96fun_name(const vector_dist_expression<prp1,v1> & va)\
97{\
98 vector_dist_expression_op<vector_dist_expression<prp1,v1>,void,OP_ID> exp_sum(va);\
99\
100 return exp_sum;\
101}
102
103CREATE_VDIST_ARG_FUNC(norm,norm,VECT_NORM)
104CREATE_VDIST_ARG_FUNC(norm2,norm2,VECT_NORM2)
105CREATE_VDIST_ARG_FUNC(abs,abs,POINT_ABS)
106CREATE_VDIST_ARG_FUNC(exp,exp,POINT_EXP)
107CREATE_VDIST_ARG_FUNC(exp2,exp2,POINT_EXP2)
108CREATE_VDIST_ARG_FUNC(expm1,expm1,POINT_EXPM1)
109CREATE_VDIST_ARG_FUNC(log,log,POINT_LOG)
110CREATE_VDIST_ARG_FUNC(log10,log10,POINT_LOG10)
111CREATE_VDIST_ARG_FUNC(log2,log2,POINT_LOG2)
112CREATE_VDIST_ARG_FUNC(log1p,log1p,POINT_LOG1P)
113CREATE_VDIST_ARG_FUNC(sqrt,sqrt,POINT_SQRT)
114CREATE_VDIST_ARG_FUNC(cbrt,cbrt,POINT_CBRT)
115CREATE_VDIST_ARG_FUNC(sin,sin,POINT_SIN)
116CREATE_VDIST_ARG_FUNC(cos,cos,POINT_COS)
117CREATE_VDIST_ARG_FUNC(tan,tan,POINT_TAN)
118CREATE_VDIST_ARG_FUNC(asin,asin,POINT_ASIN)
119CREATE_VDIST_ARG_FUNC(acos,acos,POINT_ACOS)
120CREATE_VDIST_ARG_FUNC(atan,atan,POINT_ATAN)
121CREATE_VDIST_ARG_FUNC(sinh,sinh,POINT_SINH)
122CREATE_VDIST_ARG_FUNC(cosh,cosh,POINT_COSH)
123CREATE_VDIST_ARG_FUNC(tanh,tanh,POINT_TANH)
124CREATE_VDIST_ARG_FUNC(asinh,asinh,POINT_ASINH)
125CREATE_VDIST_ARG_FUNC(acosh,acosh,POINT_ACOSH)
126CREATE_VDIST_ARG_FUNC(atanh,atanh,POINT_ATANH)
127CREATE_VDIST_ARG_FUNC(erf,erf,POINT_ERF)
128CREATE_VDIST_ARG_FUNC(erfc,erfc,POINT_ERFC)
129CREATE_VDIST_ARG_FUNC(tgamma,tgamma,POINT_TGAMMA)
130CREATE_VDIST_ARG_FUNC(lgamma,lgamma,POINT_LGAMMA)
131CREATE_VDIST_ARG_FUNC(ceil,ceil,POINT_CEIL)
132CREATE_VDIST_ARG_FUNC(floor,floor,POINT_FLOOR)
133CREATE_VDIST_ARG_FUNC(trunc,trunc,POINT_TRUNC)
134CREATE_VDIST_ARG_FUNC(round,round,POINT_ROUND)
135CREATE_VDIST_ARG_FUNC(nearbyint,nearbyint,POINT_NEARBYINT)
136CREATE_VDIST_ARG_FUNC(rint,rint,POINT_RINT)
137
138
139
145#define CREATE_VDIST_ARG2_FUNC(fun_base,fun_name,OP_ID) \
146\
147\
148template <typename exp1,typename exp2>\
149class vector_dist_expression_op<exp1,exp2,OP_ID>\
150{\
151 const exp1 o1;\
152 const exp2 o2;\
153\
154public:\
155\
156 typedef std::integral_constant<bool,exp1::is_ker::value || exp1::is_ker::value> is_ker;\
157\
158 typedef typename vector_result<typename exp1::vtype,typename exp2::vtype>::type vtype;\
159\
160 typedef typename vector_is_sort_result<exp1::is_sort::value,exp2::is_sort::value>::type is_sort;\
161\
162 typedef typename nn_type_result<typename exp1::NN_type,typename exp2::NN_type>::type NN_type;\
163\
164 inline NN_type * getNN()\
165 {\
166 return nn_type_result<typename exp1::NN_type,typename exp2::NN_type>::getNN(o1,o2);\
167 }\
168\
169 vtype & getVector()\
170 {\
171 return vector_result<typename exp1::vtype,typename exp2::vtype>::getVector(o1,o2);\
172 }\
173 const vtype & getVector() const\
174 {\
175 return vector_result<typename exp1::vtype,typename exp2::vtype>::getVector(o1,o2);\
176 }\
177\
178\
179 vector_dist_expression_op(const exp1 & o1, const exp2 & o2)\
180 :o1(o1),o2(o2)\
181 {}\
182\
183 inline void init() const\
184 {\
185 o1.init();\
186 o2.init();\
187 }\
188\
189 template<typename r_type=typename std::remove_reference<decltype(fun_base(o1.value(vect_dist_key_dx(0)),o2.value(vect_dist_key_dx(0)) ))>::type > inline r_type value(const vect_dist_key_dx & key) const\
190 {\
191 return fun_base(o1.value(key),o2.value(key));\
192 }\
193};\
194\
195\
196template<unsigned int p1, unsigned int p2, typename v1, typename v2>\
197inline vector_dist_expression_op<vector_dist_expression<p1,v1>,vector_dist_expression<p2,v2>,OP_ID>\
198fun_name(const vector_dist_expression<p1,v1> & va, const vector_dist_expression<p2,v2> & vb)\
199{\
200 vector_dist_expression_op<vector_dist_expression<p1,v1>,vector_dist_expression<p2,v2>,OP_ID> exp_sum(va,vb);\
201\
202 return exp_sum;\
203}\
204\
205template<typename exp1 , typename exp2, unsigned int op1, unsigned int prp1, typename v1>\
206inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,vector_dist_expression<prp1,v1>,OP_ID>\
207fun_name(const vector_dist_expression_op<exp1,exp2,op1> & va, const vector_dist_expression<prp1,v1> & vb)\
208{\
209 vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,vector_dist_expression<prp1,v1>,OP_ID> exp_sum(va,vb);\
210\
211 return exp_sum;\
212}\
213\
214template<typename exp1 , typename exp2, unsigned int op1, unsigned int prp1, typename v1>\
215inline vector_dist_expression_op<vector_dist_expression<prp1,v1>,vector_dist_expression_op<exp1,exp2,op1>,OP_ID>\
216fun_name(const vector_dist_expression<prp1,v1> & va, const vector_dist_expression_op<exp1,exp2,op1> & vb)\
217{\
218 vector_dist_expression_op<vector_dist_expression<prp1,v1>,vector_dist_expression_op<exp1,exp2,op1>,OP_ID> exp_sum(va,vb);\
219\
220 return exp_sum;\
221}\
222\
223template<typename exp1 , typename exp2, unsigned int op1, typename exp3 , typename exp4, unsigned int op2>\
224inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,vector_dist_expression_op<exp3,exp4,op2>,OP_ID>\
225fun_name(const vector_dist_expression_op<exp1,exp2,op1> & va, const vector_dist_expression_op<exp3,exp4,op2> & vb)\
226{\
227 vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,vector_dist_expression_op<exp3,exp4,op2>,OP_ID> exp_sum(va,vb);\
228\
229 return exp_sum;\
230}\
231\
232template<unsigned int prp1 , typename v1>\
233inline vector_dist_expression_op<vector_dist_expression<prp1,v1>,vector_dist_expression<0,double>,OP_ID>\
234fun_name(const vector_dist_expression<prp1,v1> & va, double d)\
235{\
236 vector_dist_expression_op<vector_dist_expression<prp1,v1>,vector_dist_expression<0,double>,OP_ID> exp_sum(va,vector_dist_expression<0,double>(d));\
237\
238 return exp_sum;\
239}\
240\
241template<unsigned int prp1 , typename v1>\
242inline vector_dist_expression_op<vector_dist_expression<0,double>,vector_dist_expression<prp1,v1>,OP_ID>\
243fun_name(double d, const vector_dist_expression<prp1,v1> & vb)\
244{\
245 vector_dist_expression_op<vector_dist_expression<0,double>,vector_dist_expression<prp1,v1>,OP_ID> exp_sum(vector_dist_expression<0,double>(d),vb);\
246\
247 return exp_sum;\
248}\
249\
250template<typename exp1 , typename exp2, unsigned int op1>\
251inline vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,vector_dist_expression<0,double>,OP_ID>\
252fun_name(const vector_dist_expression_op<exp1,exp2,op1> & va, double d)\
253{\
254 vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,vector_dist_expression<0,double>,OP_ID> exp_sum(va,vector_dist_expression<0,double>(d));\
255\
256 return exp_sum;\
257}\
258\
259template<typename exp1 , typename exp2, unsigned int op1>\
260inline vector_dist_expression_op<vector_dist_expression<0,double>,vector_dist_expression_op<exp1,exp2,op1>,OP_ID>\
261fun_name(double d, const vector_dist_expression_op<exp1,exp2,op1> & va)\
262{\
263 vector_dist_expression_op<vector_dist_expression_op<exp1,exp2,op1>,vector_dist_expression<0,double>,OP_ID> exp_sum(vector_dist_expression<0,double>(d),va);\
264\
265 return exp_sum;\
266}
267
268CREATE_VDIST_ARG2_FUNC(pmul,pmul,VECT_PMUL)
269
270
271
272template<typename val_type, bool is_sort, bool is_scalar = is_Point<val_type>::type::value>
274{
276
277 template<typename vector_type, typename expression>
278 static void process(val_type & val, vector_type & ve, expression & o1)
279 {
280#ifdef __NVCC__
281
282 auto vek = ve.toKernel();
284
285 exp_tmp2[0].resize(sizeof(val_type));
286
287 auto & v_cl = create_vcluster<CudaMemory>();
288
289 openfpm::reduce((val_type *)ve.template getDeviceBuffer<0>(), ve.size(), (val_type *)(exp_tmp2[0].getDevicePointer()), gpu::plus_t<val_type>(), v_cl.getgpuContext());
290
291 exp_tmp2[0].deviceToHost();
292
293 val = *(val_type *)(exp_tmp2[0].getPointer());
294#else
295 std::cout << __FILE__ << ":" << __LINE__ << " error: to make expression work on GPU the file must be compiled on GPU" << std::endl;
296#endif
297 }
298};
299
300template<typename val_type, bool is_sort>
301struct point_scalar_process<val_type,is_sort,true>
302{
303 typedef val_type type;
304
305 template<typename vector_type, typename expression>
306 static void process(val_type & val, vector_type & ve, expression & o1)
307 {
308#ifdef __NVCC__
309
310// auto ite = ve.getGPUIterator(256);
311
312// compute_expr_ker_vv<0,val_type::dims><<<ite.wthr,ite.thr>>>(ve.toKernel(),o1);
313
314 auto vek = ve.toKernel();
315 vector_dist_op_compute_op<0,is_sort,comp_dev>::template compute_expr_vv<val_type::dims>(vek,o1);
316
317 exp_tmp2[0].resize(sizeof(val_type));
318
319 size_t offset = 0;
320
321 auto & v_cl = create_vcluster<CudaMemory>();
322
323 for (size_t i = 0 ; i < val_type::dims ; i++)
324 {
325 openfpm::reduce(&((typename val_type::coord_type *)ve.template getDeviceBuffer<0>())[offset],
326 ve.size(),
327 (typename val_type::coord_type *)(exp_tmp2[0].getDevicePointer()),
329 v_cl.getgpuContext());
330
331 exp_tmp2[0].deviceToHost();
332
333 val.get(i) = *(typename val_type::coord_type *)exp_tmp2[0].getPointer();
334
335 offset += ve.capacity();
336 }
337
338#else
339 std::cout << __FILE__ << ":" << __LINE__ << " error: to make expression work on GPU the file must be compiled on GPU" << std::endl;
340#endif
341 }
342};
343
344
345template<bool is_device>
347{
348 template<typename is_sort, typename o1_type, typename val_type>
349 static void red(o1_type & o1, val_type & val)
350 {
351
352#ifdef __NVCC__
353
354 // we have to do it on GPU
355
360
361 auto & orig_v = o1.getVector();
362
363 if (exp_tmp.ref() == 0)
364 {exp_tmp.incRef();}
365
366 ve.setMemory(exp_tmp);
367 ve.resize(orig_v.size_local());
368
370#else
371 std::cout << __FILE__ << ":" << __LINE__ << " error, to use expression on GPU you must compile with nvcc compiler " << std::endl;
372#endif
373 }
374};
375
376template<>
378{
379 template<typename is_sort, typename o1_type, typename val_type>
380 static void red(o1_type & o1, val_type & val)
381 {
382 const auto & orig_v = o1.getVector();
383
384 o1.init();
385
386 val = 0.0;
387
388 auto it = orig_v.getDomainIterator();
389
390 while (it.isNext())
391 {
392 auto key = it.get();
393
394 val += o1.value(key);
395
396 ++it;
397 }
398 }
399};
400
407template <typename exp1>
408class vector_dist_expression_op<exp1,void,VECT_SUM_REDUCE>
409{
410
412 const exp1 o1;
413
415 typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx()))>::rtype rtype;
416
418 mutable typename std::remove_reference<rtype>::type val;
419
420public:
421
423 typedef typename exp1::is_ker is_ker;
424
426 typedef typename vector_result<typename exp1::vtype,void>::type vtype;
427
429 typedef typename vector_is_sort_result<exp1::is_sort::value,false>::type is_sort;
430
432 typedef typename nn_type_result<typename exp1::NN_type,void>::type NN_type;
433
436 :o1(o1),val(0)
437 {}
438
440 // this produce a cache for the calculated value
441 inline void init() const
442 {
444 }
445
451 inline NN_type * getNN() const
452 {
454 }
455
457 inline typename std::remove_reference<rtype>::type get()
458 {
459 init();
460 return value(vect_dist_key_dx());
461 }
462
464 template<typename r_type= typename std::remove_reference<rtype>::type >
465 __device__ __host__ inline r_type value(const vect_dist_key_dx & key) const
466 {
467 return val;
468 }
469
478 {
479 return o1.getVector();
480 }
481
489 const vtype & getVector() const
490 {
491 return o1.getVector();
492 }
493};
494
496template<typename exp1, typename exp2_, unsigned int op1>
499{
501
502 return exp_sum;
503}
504
506template<unsigned int prp1, typename v1>
508rsum(const vector_dist_expression<prp1,v1> & va)
509{
510 vector_dist_expression_op<vector_dist_expression<prp1,v1>,void,VECT_SUM_REDUCE> exp_sum(va);
511
512 return exp_sum;
513}
514
515namespace openfpm
516{
521 template <typename T, typename P> auto distance(T exp1, P exp2) -> decltype(norm(exp1 - exp2))
522 {
523 return norm(exp1 - exp2);
524 }
525}
526
527
534template <typename exp1>
535class vector_dist_expression_op<exp1,void,VECT_NORM_INF>
536{
537
539 const exp1 o1;
540
542 typedef typename apply_kernel_rtype<decltype(o1.value(vect_dist_key_dx()))>::rtype rtype;
543
545 mutable typename std::remove_reference<rtype>::type val;
546
547public:
548
550 typedef typename exp1::is_ker is_ker;
551
553 typedef typename vector_result<typename exp1::vtype,void>::type vtype;
554
556 typedef typename vector_is_sort_result<exp1::is_sort::value,false>::type is_sort;
557
559 typedef typename nn_type_result<typename exp1::NN_type,void>::type NN_type;
560
563 :o1(o1),val(0)
564 {}
565
567 // this produce a cache for the calculated value
568 inline void init() const
569 {
570 if (exp1::is_ker::value == true)
571 {
572
573#ifdef __NVCC__
574 typedef decltype(val) val_type;
575
576 // we have to do it on GPU
577
582
583 auto & orig_v = o1.getVector();
584
585 if (exp_tmp.ref() == 0)
586 {exp_tmp.incRef();}
587
588 ve.setMemory(exp_tmp);
589 ve.resize(orig_v.size_local());
590
592#else
593 std::cout << __FILE__ << ":" << __LINE__ << " error, to use expression on GPU you must compile with nvcc compiler " << std::endl;
594#endif
595 }
596 else
597 {
598 const auto & orig_v = o1.getVector();
599
600 o1.init();
601
602 val = 0.0;
603
604 auto it = orig_v.getDomainIterator();
605
606 while (it.isNext())
607 {
608 auto key = it.get();
609 if(fabs(o1.value(key))>val) {
610 val = fabs(o1.value(key));
611 }
612 ++it;
613 }
614 }
615 }
616
622 inline NN_type * getNN() const
623 {
625 }
626
628 inline typename std::remove_reference<rtype>::type get()
629 {
630 init();
631 return value(vect_dist_key_dx());
632 }
633
635 template<typename r_type= typename std::remove_reference<rtype>::type > inline r_type value(const vect_dist_key_dx & key) const
636 {
637 return val;
638 }
639
641 template<typename r_type= typename std::remove_reference<rtype>::type > inline r_type getReduction() const
642 {
643 return val;
644 }
645
654 {
655 return o1.getVector();
656 }
657
665 const vtype & getVector() const
666 {
667 return o1.getVector();
668 }
669};
670
672template<typename exp1, typename exp2_, unsigned int op1>
675{
677
678 return exp_sum;
679}
680
682template<unsigned int prp1, typename v1>
684norm_inf(const vector_dist_expression<prp1,v1> & va)
685{
686 vector_dist_expression_op<vector_dist_expression<prp1,v1>,void,VECT_NORM_INF> exp_sum(va);
687
688 return exp_sum;
689}
690
691#endif /* OPENFPM_NUMERICS_SRC_OPERATORS_VECTOR_VECTOR_DIST_OPERATORS_FUNCTIONS_HPP_ */
Test structure used for several test.
Grow policy define how the vector should grow every time we exceed the size.
Implementation of 1-D std::vector like structure.
Grid key for a distributed grid.
vector_result< typenameexp1::vtype, void >::type vtype
return the vector type on which this expression operate
void init() const
sum reduction require initialization where we calculate the reduction
const vtype & getVector() const
Return the vector on which is acting.
r_type getReduction() const
it return the result of the expression for ODEINT
std::remove_reference< rtype >::type val
return type of the calculated value (without reference)
vector_dist_expression_op(const exp1 &o1)
constructor from an epxression exp1 and a vector vd
exp1::is_ker is_ker
Indicate if it is an in kernel expression.
std::remove_reference< rtype >::type get()
it return the result of the expression
r_type value(const vect_dist_key_dx &key) const
it return the result of the expression (precalculated before)
vector_is_sort_result< exp1::is_sort::value, false >::type is_sort
result for is sort
apply_kernel_rtype< decltype(o1.value(vect_dist_key_dx()))>::rtype rtype
return type of this expression
nn_type_result< typenameexp1::NN_type, void >::type NN_type
NN_type.
apply_kernel_rtype< decltype(o1.value(vect_dist_key_dx()))>::rtype rtype
return type of this expression
std::remove_reference< rtype >::type get()
it return the result of the expression
void init() const
sum reduction require initialization where we calculate the reduction
vector_is_sort_result< exp1::is_sort::value, false >::type is_sort
result for is sort
vector_dist_expression_op(const exp1 &o1)
constructor from an epxression exp1 and a vector vd
nn_type_result< typenameexp1::NN_type, void >::type NN_type
NN_type.
__device__ __host__ r_type value(const vect_dist_key_dx &key) const
it return the result of the expression (precalculated before)
const vtype & getVector() const
Return the vector on which is acting.
vector_result< typenameexp1::vtype, void >::type vtype
return the vector type on which this expression operate
std::remove_reference< rtype >::type val
return type of the calculated value (without reference)
exp1::is_ker is_ker
Indicate if it is an in kernel expression.
Unknown operation specialization.
Main class that encapsulate a vector properties operand to be used for expressions construction.
Distributed vector.
convert a type into constant type
auto distance(T exp1, P exp2) -> decltype(norm(exp1 - exp2))
General distance formula.
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
It give the return type of the expression if applicable.
Transform the boost::fusion::vector into memory specification (memory_traits)
temporal buffer for reductions