| /* |
| [auto_generated] |
| boost/numeric/odeint/external/compute/compute_operations.hpp |
| |
| [begin_description] |
| Operations of Boost.Compute zipped iterators. Is the counterpart of the compute_algebra. |
| [end_description] |
| |
| Copyright 2009-2011 Karsten Ahnert |
| Copyright 2009-2011 Mario Mulansky |
| |
| Distributed under the Boost Software License, Version 1.0. |
| (See accompanying file LICENSE_1_0.txt or |
| copy at http://www.boost.org/LICENSE_1_0.txt) |
| */ |
| |
| |
| #ifndef BOOST_NUMERIC_ODEINT_EXTERNAL_COMPUTE_COMPUTE_OPERATIONS_HPP_DEFINED |
| #define BOOST_NUMERIC_ODEINT_EXTERNAL_COMPUTE_COMPUTE_OPERATIONS_HPP_DEFINED |
| |
| #include <boost/preprocessor/repetition.hpp> |
| #include <boost/compute.hpp> |
| |
| namespace boost { |
| namespace numeric { |
| namespace odeint { |
| |
| struct compute_operations { |
| |
| #define BOOST_ODEINT_COMPUTE_TEMPL_FAC(z, n, unused) \ |
| , class Fac ## n = BOOST_PP_CAT(Fac, BOOST_PP_DEC(n)) |
| |
| #define BOOST_ODEINT_COMPUTE_MEMB_FAC(z, n, unused) \ |
| const Fac ## n m_alpha ## n; |
| |
| #define BOOST_ODEINT_COMPUTE_PRM_FAC(z, n, unused) \ |
| BOOST_PP_COMMA_IF(n) const Fac ## n alpha ## n |
| |
| #define BOOST_ODEINT_COMPUTE_INIT_FAC(z, n, unused) \ |
| BOOST_PP_COMMA_IF(n) m_alpha ## n (alpha ## n) |
| |
| #define BOOST_ODEINT_COMPUTE_PRM_STATE(z, n, unused) \ |
| BOOST_PP_COMMA_IF(n) StateType ## n &s ## n |
| |
| #define BOOST_ODEINT_COMPUTE_BEGIN_STATE(z, n, unused) \ |
| BOOST_PP_COMMA_IF( BOOST_PP_DEC(n) ) s ## n.begin() |
| |
| #define BOOST_ODEINT_COMPUTE_END_STATE(z, n, unused) \ |
| BOOST_PP_COMMA_IF( BOOST_PP_DEC(n) ) s ## n.end() |
| |
| #define BOOST_ODEINT_COMPUTE_LAMBDA(z, n, unused) \ |
| BOOST_PP_EXPR_IF(n, +) m_alpha ## n * bc::lambda::get< n >(bc::_1) |
| |
| #define BOOST_ODEINT_COMPUTE_OPERATIONS(z, n, unused) \ |
| template< \ |
| class Fac0 = double \ |
| BOOST_PP_REPEAT_FROM_TO(1, n, BOOST_ODEINT_COMPUTE_TEMPL_FAC, ~) \ |
| > \ |
| struct scale_sum ## n { \ |
| BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_MEMB_FAC, ~) \ |
| scale_sum ## n( \ |
| BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_PRM_FAC, ~) \ |
| ) \ |
| : BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_INIT_FAC, ~) \ |
| { } \ |
| template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), class StateType) > \ |
| void operator()( \ |
| BOOST_PP_REPEAT( \ |
| BOOST_PP_INC(n), \ |
| BOOST_ODEINT_COMPUTE_PRM_STATE, ~) \ |
| ) const \ |
| { \ |
| namespace bc = boost::compute; \ |
| bc::transform( \ |
| bc::make_zip_iterator( \ |
| boost::make_tuple( \ |
| BOOST_PP_REPEAT_FROM_TO( \ |
| 1, BOOST_PP_INC(n), \ |
| BOOST_ODEINT_COMPUTE_BEGIN_STATE, ~) \ |
| ) \ |
| ), \ |
| bc::make_zip_iterator( \ |
| boost::make_tuple( \ |
| BOOST_PP_REPEAT_FROM_TO( \ |
| 1, BOOST_PP_INC(n), \ |
| BOOST_ODEINT_COMPUTE_END_STATE, ~) \ |
| ) \ |
| ), \ |
| s0.begin(), \ |
| BOOST_PP_REPEAT(n, BOOST_ODEINT_COMPUTE_LAMBDA, ~) \ |
| ); \ |
| } \ |
| }; |
| |
| BOOST_PP_REPEAT_FROM_TO(2, 8, BOOST_ODEINT_COMPUTE_OPERATIONS, ~) |
| |
| #undef BOOST_ODEINT_COMPUTE_TEMPL_FAC |
| #undef BOOST_ODEINT_COMPUTE_MEMB_FAC |
| #undef BOOST_ODEINT_COMPUTE_PRM_FAC |
| #undef BOOST_ODEINT_COMPUTE_INIT_FAC |
| #undef BOOST_ODEINT_COMPUTE_PRM_STATE |
| #undef BOOST_ODEINT_COMPUTE_BEGIN_STATE |
| #undef BOOST_ODEINT_COMPUTE_END_STATE |
| #undef BOOST_ODEINT_COMPUTE_LAMBDA |
| #undef BOOST_ODEINT_COMPUTE_OPERATIONS |
| |
| template<class Fac1 = double, class Fac2 = Fac1> |
| struct scale_sum_swap2 { |
| const Fac1 m_alpha1; |
| const Fac2 m_alpha2; |
| |
| scale_sum_swap2(const Fac1 alpha1, const Fac2 alpha2) |
| : m_alpha1(alpha1), m_alpha2(alpha2) { } |
| |
| template<class State0, class State1, class State2> |
| void operator()(State0 &s0, State1 &s1, State2 &s2) const { |
| namespace bc = boost::compute; |
| |
| bc::command_queue &queue = bc::system::default_queue(); |
| const bc::context &context = queue.get_context(); |
| |
| const char source[] = BOOST_COMPUTE_STRINGIZE_SOURCE( |
| kernel void scale_sum_swap2( |
| F1 a1, F2 a2, |
| global T0 *x0, global T1 *x1, global T2 *x2, |
| ) |
| { |
| uint i = get_global_id(0); |
| T0 tmp = x0[i]; |
| x0[i] = a1 * x1[i] + a2 * x2[i]; |
| x1[i] = tmp; |
| } |
| ); |
| |
| std::stringstream options; |
| options |
| << " -DT0=" << bc::type_name<typename State0::value_type>() |
| << " -DT1=" << bc::type_name<typename State1::value_type>() |
| << " -DT2=" << bc::type_name<typename State2::value_type>() |
| << " -DF1=" << bc::type_name<Fac1>() |
| << " -DF2=" << bc::type_name<Fac2>(); |
| |
| bc::program program = |
| bc::program::build_with_source(source, context, options.str()); |
| |
| bc::kernel kernel(program, "scale_sum_swap2"); |
| kernel.set_arg(0, m_alpha1); |
| kernel.set_arg(1, m_alpha2); |
| kernel.set_arg(2, s0.get_buffer()); |
| kernel.set_arg(3, s1.get_buffer()); |
| kernel.set_arg(4, s2.get_buffer()); |
| |
| queue.enqueue_1d_range_kernel(kernel, 0, s0.size()); |
| |
| } |
| }; |
| |
| template<class Fac1 = double> |
| struct rel_error { |
| const Fac1 m_eps_abs, m_eps_rel, m_a_x, m_a_dxdt; |
| |
| rel_error(const Fac1 eps_abs, const Fac1 eps_rel, const Fac1 a_x, const Fac1 a_dxdt) |
| : m_eps_abs(eps_abs), m_eps_rel(eps_rel), m_a_x(a_x), m_a_dxdt(a_dxdt) { } |
| |
| |
| template <class State0, class State1, class State2> |
| void operator()(State0 &s0, State1 &s1, State2 &s2) const { |
| namespace bc = boost::compute; |
| using bc::_1; |
| using bc::lambda::get; |
| |
| bc::for_each( |
| bc::make_zip_iterator( |
| boost::make_tuple( |
| s0.begin(), |
| s1.begin(), |
| s2.begin() |
| ) |
| ), |
| bc::make_zip_iterator( |
| boost::make_tuple( |
| s0.end(), |
| s1.end(), |
| s2.end() |
| ) |
| ), |
| get<0>(_1) = abs( get<0>(_1) ) / |
| (m_eps_abs + m_eps_rel * (m_a_x * abs(get<1>(_1) + m_a_dxdt * abs(get<2>(_1))))) |
| ); |
| } |
| }; |
| }; |
| |
| } // odeint |
| } // numeric |
| } // boost |
| |
| #endif // BOOST_NUMERIC_ODEINT_EXTERNAL_COMPUTE_COMPUTE_OPERATIONS_HPP_DEFINED |