1/*
2 * tokernel_transformation.hpp
3 *
4 * Created on: Aug 29, 2018
5 * Author: i-bird
6 */
7
8#ifndef TOKERNEL_TRANSFORMATION_HPP_
9#define TOKERNEL_TRANSFORMATION_HPP_
10
11#include "data_type/aggregate.hpp"
12
13/*! \brief this set of meta-functions traverse at compile time the tree-structure of types in Depth-first search.
14 * and transform any root node of type vector into vector_gpu_ker
15 *
16 * Consider
17 *
18 * vector_gpu<aggregate<int,vector_gpu<aggregate<int,float>>>>
19 *
20 * is a tree in this form
21 *
22 * \verbatim
23 *
24 * * vector_gpu<aggregate<...>>
25 * / \
26 * / \
27 * / \
28 * int * vector_gpu<aggregate<...>>
29 * / \
30 * / \
31 * / \
32 * int float
33 *
34 * \endverbatim
35 *
36 * The vector is transformed at compile-time into
37 *
38 * is a tree in this form
39 *
40 * \verbatim
41 *
42 * * vector_gpu_ker<aggregate<...>>
43 * / \
44 * / \
45 * / \
46 * int * vector_gpu_ker<aggregate<...>>
47 * / \
48 * / \
49 * / \
50 * int float
51 *
52 * \endverbatim
53 *
54 *
55 */
56
57namespace openfpm
58{
59
60 /*! \brief grid interface available when on gpu
61 *
62 * \tparam n_buf number of template buffers
63 *
64 */
65
66 template<typename T, template <typename> class layout_base>
67 struct vector_gpu_ker;
68}
69
70// Definition of the box
71template<unsigned int dim , typename T> class Box;
72
73template<template <typename> class layout_base, typename T, int = is_vector_native<T>::value + 2*is_vector_dist<T>::value + 4*is_gpu_celllist<T>::value >
74struct toKernel_transform;
75
76template<template <typename> class layout_base, typename T, typename ... args>
77struct apply_trasform_impl
78{
79 typedef void type;
80};
81
82template<template <typename> class layout_base, typename T, int impl, typename ... args>
83struct aggregate_or_known_type
84{
85 typedef aggregate<typename toKernel_transform<layout_base,args>::type ... > type;
86};
87
88template<template <typename> class layout_base, typename T, typename ... args>
89struct apply_trasform_impl<layout_base,T,boost::fusion::vector<args...>>
90{
91 static const int impl = is_aggregate<T>::value + is_Box<T>::value * 2 + is_Point<T>::value * 4;
92
93 typedef typename aggregate_or_known_type<layout_base,T,impl,args...>::type type;
94};
95
96
97template<template <typename> class layout_base,typename T>
98struct apply_transform
99{
100 typedef typename apply_trasform_impl<layout_base,T,typename T::type>::type type;
101};
102
103/////////////////////////////////////////////// TRANSFORMER NODE /////////////////////////////////////////////////
104
105template<template <typename> class layout_base, typename T >
106struct toKernel_transform<layout_base,T,0>
107{
108 typedef T type;
109};
110
111
112template<template <typename> class layout_base, typename T>
113struct toKernel_transform<layout_base,T,1>
114{
115 typedef typename apply_transform<layout_base,typename T::value_type>::type aggr;
116
117 typedef openfpm::vector_gpu_ker<aggr,layout_base> type;
118};
119
120/////////////////////////////////////////////////// KNOWN TYPE SPECIALIZATION TERMINATORS //////////////////////
121
122template<template <typename> class layout_base,typename T, typename ... args>
123struct aggregate_or_known_type<layout_base,T,2,args ...>
124{
125 typedef Box<T::dims,typename T::btype > type;
126};
127
128template<template <typename> class layout_base,typename T, typename ... args>
129struct aggregate_or_known_type<layout_base,T,4,args ...>
130{
131 typedef Point<T::dims,typename T::coord_type > type;
132};
133
134#endif /* TOKERNEL_TRANSFORMATION_HPP_ */
135