diff options
Diffstat (limited to 'boost/numeric/odeint/external/compute/compute_operations.hpp')
-rw-r--r-- | boost/numeric/odeint/external/compute/compute_operations.hpp | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/boost/numeric/odeint/external/compute/compute_operations.hpp b/boost/numeric/odeint/external/compute/compute_operations.hpp new file mode 100644 index 0000000000..58d5f692ff --- /dev/null +++ b/boost/numeric/odeint/external/compute/compute_operations.hpp @@ -0,0 +1,198 @@ +/* + [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 |