]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | [auto_generated] | |
3 | boost/numeric/odeint/external/compute/compute_operations.hpp | |
4 | ||
5 | [begin_description] | |
6 | Operations of Boost.Compute zipped iterators. Is the counterpart of the compute_algebra. | |
7 | [end_description] | |
8 | ||
9 | Copyright 2009-2011 Karsten Ahnert | |
10 | Copyright 2009-2011 Mario Mulansky | |
11 | ||
12 | Distributed under the Boost Software License, Version 1.0. | |
13 | (See accompanying file LICENSE_1_0.txt or | |
14 | copy at http://www.boost.org/LICENSE_1_0.txt) | |
15 | */ | |
16 | ||
17 | ||
18 | #ifndef BOOST_NUMERIC_ODEINT_EXTERNAL_COMPUTE_COMPUTE_OPERATIONS_HPP_DEFINED | |
19 | #define BOOST_NUMERIC_ODEINT_EXTERNAL_COMPUTE_COMPUTE_OPERATIONS_HPP_DEFINED | |
20 | ||
21 | #include <boost/preprocessor/repetition.hpp> | |
22 | #include <boost/compute.hpp> | |
23 | ||
24 | namespace boost { | |
25 | namespace numeric { | |
26 | namespace odeint { | |
27 | ||
28 | struct compute_operations { | |
29 | ||
30 | #define BOOST_ODEINT_COMPUTE_TEMPL_FAC(z, n, unused) \ | |
31 | , class Fac ## n = BOOST_PP_CAT(Fac, BOOST_PP_DEC(n)) | |
32 | ||
33 | #define BOOST_ODEINT_COMPUTE_MEMB_FAC(z, n, unused) \ | |
34 | const Fac ## n m_alpha ## n; | |
35 | ||
36 | #define BOOST_ODEINT_COMPUTE_PRM_FAC(z, n, unused) \ | |
37 | BOOST_PP_COMMA_IF(n) const Fac ## n alpha ## n | |
38 | ||
39 | #define BOOST_ODEINT_COMPUTE_INIT_FAC(z, n, unused) \ | |
40 | BOOST_PP_COMMA_IF(n) m_alpha ## n (alpha ## n) | |
41 | ||
42 | #define BOOST_ODEINT_COMPUTE_PRM_STATE(z, n, unused) \ | |
43 | BOOST_PP_COMMA_IF(n) StateType ## n &s ## n | |
44 | ||
45 | #define BOOST_ODEINT_COMPUTE_BEGIN_STATE(z, n, unused) \ | |
46 | BOOST_PP_COMMA_IF( BOOST_PP_DEC(n) ) s ## n.begin() | |
47 | ||
48 | #define BOOST_ODEINT_COMPUTE_END_STATE(z, n, unused) \ | |
49 | BOOST_PP_COMMA_IF( BOOST_PP_DEC(n) ) s ## n.end() | |
50 | ||
51 | #define BOOST_ODEINT_COMPUTE_LAMBDA(z, n, unused) \ | |
52 | BOOST_PP_EXPR_IF(n, +) m_alpha ## n * bc::lambda::get< n >(bc::_1) | |
53 | ||
54 | #define BOOST_ODEINT_COMPUTE_OPERATIONS(z, n, unused) \ | |
55 | template< \ | |
56 | class Fac0 = double \ | |
57 | BOOST_PP_REPEAT_FROM_TO(1, n, BOOST_ODEINT_COMPUTE_TEMPL_FAC, ~) \ | |
58 | > \ | |
59 | struct scale_sum ## n { \ | |
60 | BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_MEMB_FAC, ~) \ | |
61 | scale_sum ## n( \ | |
62 | BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_PRM_FAC, ~) \ | |
63 | ) \ | |
64 | : BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_INIT_FAC, ~) \ | |
65 | { } \ | |
66 | template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), class StateType) > \ | |
67 | void operator()( \ | |
68 | BOOST_PP_REPEAT( \ | |
69 | BOOST_PP_INC(n), \ | |
70 | BOOST_ODEINT_COMPUTE_PRM_STATE, ~) \ | |
71 | ) const \ | |
72 | { \ | |
73 | namespace bc = boost::compute; \ | |
74 | bc::transform( \ | |
75 | bc::make_zip_iterator( \ | |
76 | boost::make_tuple( \ | |
77 | BOOST_PP_REPEAT_FROM_TO( \ | |
78 | 1, BOOST_PP_INC(n), \ | |
79 | BOOST_ODEINT_COMPUTE_BEGIN_STATE, ~) \ | |
80 | ) \ | |
81 | ), \ | |
82 | bc::make_zip_iterator( \ | |
83 | boost::make_tuple( \ | |
84 | BOOST_PP_REPEAT_FROM_TO( \ | |
85 | 1, BOOST_PP_INC(n), \ | |
86 | BOOST_ODEINT_COMPUTE_END_STATE, ~) \ | |
87 | ) \ | |
88 | ), \ | |
89 | s0.begin(), \ | |
90 | BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_LAMBDA, ~) \ | |
91 | ); \ | |
92 | } \ | |
93 | }; | |
94 | ||
95 | BOOST_PP_REPEAT_FROM_TO(2, 8, BOOST_ODEINT_COMPUTE_OPERATIONS, ~) | |
96 | ||
97 | #undef BOOST_ODEINT_COMPUTE_TEMPL_FAC | |
98 | #undef BOOST_ODEINT_COMPUTE_MEMB_FAC | |
99 | #undef BOOST_ODEINT_COMPUTE_PRM_FAC | |
100 | #undef BOOST_ODEINT_COMPUTE_INIT_FAC | |
101 | #undef BOOST_ODEINT_COMPUTE_PRM_STATE | |
102 | #undef BOOST_ODEINT_COMPUTE_BEGIN_STATE | |
103 | #undef BOOST_ODEINT_COMPUTE_END_STATE | |
104 | #undef BOOST_ODEINT_COMPUTE_LAMBDA | |
105 | #undef BOOST_ODEINT_COMPUTE_OPERATIONS | |
106 | ||
107 | template<class Fac1 = double, class Fac2 = Fac1> | |
108 | struct scale_sum_swap2 { | |
109 | const Fac1 m_alpha1; | |
110 | const Fac2 m_alpha2; | |
111 | ||
112 | scale_sum_swap2(const Fac1 alpha1, const Fac2 alpha2) | |
113 | : m_alpha1(alpha1), m_alpha2(alpha2) { } | |
114 | ||
115 | template<class State0, class State1, class State2> | |
116 | void operator()(State0 &s0, State1 &s1, State2 &s2) const { | |
117 | namespace bc = boost::compute; | |
118 | ||
119 | bc::command_queue &queue = bc::system::default_queue(); | |
120 | const bc::context &context = queue.get_context(); | |
121 | ||
122 | const char source[] = BOOST_COMPUTE_STRINGIZE_SOURCE( | |
123 | kernel void scale_sum_swap2( | |
124 | F1 a1, F2 a2, | |
125 | global T0 *x0, global T1 *x1, global T2 *x2, | |
126 | ) | |
127 | { | |
128 | uint i = get_global_id(0); | |
129 | T0 tmp = x0[i]; | |
130 | x0[i] = a1 * x1[i] + a2 * x2[i]; | |
131 | x1[i] = tmp; | |
132 | } | |
133 | ); | |
134 | ||
135 | std::stringstream options; | |
136 | options | |
137 | << " -DT0=" << bc::type_name<typename State0::value_type>() | |
138 | << " -DT1=" << bc::type_name<typename State1::value_type>() | |
139 | << " -DT2=" << bc::type_name<typename State2::value_type>() | |
140 | << " -DF1=" << bc::type_name<Fac1>() | |
141 | << " -DF2=" << bc::type_name<Fac2>(); | |
142 | ||
143 | bc::program program = | |
144 | bc::program::build_with_source(source, context, options.str()); | |
145 | ||
146 | bc::kernel kernel(program, "scale_sum_swap2"); | |
147 | kernel.set_arg(0, m_alpha1); | |
148 | kernel.set_arg(1, m_alpha2); | |
149 | kernel.set_arg(2, s0.get_buffer()); | |
150 | kernel.set_arg(3, s1.get_buffer()); | |
151 | kernel.set_arg(4, s2.get_buffer()); | |
152 | ||
153 | queue.enqueue_1d_range_kernel(kernel, 0, s0.size()); | |
154 | ||
155 | } | |
156 | }; | |
157 | ||
158 | template<class Fac1 = double> | |
159 | struct rel_error { | |
160 | const Fac1 m_eps_abs, m_eps_rel, m_a_x, m_a_dxdt; | |
161 | ||
162 | rel_error(const Fac1 eps_abs, const Fac1 eps_rel, const Fac1 a_x, const Fac1 a_dxdt) | |
163 | : m_eps_abs(eps_abs), m_eps_rel(eps_rel), m_a_x(a_x), m_a_dxdt(a_dxdt) { } | |
164 | ||
165 | ||
166 | template <class State0, class State1, class State2> | |
167 | void operator()(State0 &s0, State1 &s1, State2 &s2) const { | |
168 | namespace bc = boost::compute; | |
169 | using bc::_1; | |
170 | using bc::lambda::get; | |
171 | ||
172 | bc::for_each( | |
173 | bc::make_zip_iterator( | |
174 | boost::make_tuple( | |
175 | s0.begin(), | |
176 | s1.begin(), | |
177 | s2.begin() | |
178 | ) | |
179 | ), | |
180 | bc::make_zip_iterator( | |
181 | boost::make_tuple( | |
182 | s0.end(), | |
183 | s1.end(), | |
184 | s2.end() | |
185 | ) | |
186 | ), | |
187 | get<0>(_1) = abs( get<0>(_1) ) / | |
188 | (m_eps_abs + m_eps_rel * (m_a_x * abs(get<1>(_1) + m_a_dxdt * abs(get<2>(_1))))) | |
189 | ); | |
190 | } | |
191 | }; | |
192 | }; | |
193 | ||
194 | } // odeint | |
195 | } // numeric | |
196 | } // boost | |
197 | ||
198 | #endif // BOOST_NUMERIC_ODEINT_EXTERNAL_COMPUTE_COMPUTE_OPERATIONS_HPP_DEFINED |