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