How to combine boost odeint with OpenMP and boost multiprecision?

六眼飞鱼酱① 提交于 2019-12-11 16:39:22

问题


I am asking a question, which is related to the last comments in this post:

Using openmp with odeint and adaptative step sizes

In the end, the original poster asked whether or not OpenMP is compatible with boost multiprecision. I guess this problem has been solved in the meanwhile but I could not find the answer.

Hence, I tried to figure it out on my own and implemented some coupled ODEs.

#include <iostream>
#include <vector>
#include <omp.h>
#include <boost/numeric/odeint.hpp>
#include <boost/numeric/odeint/external/openmp/openmp.hpp>

#include <boost/multiprecision/gmp.hpp>
template< typename Backend, boost::multiprecision::expression_template_option Option >
struct has_value_type<boost::multiprecision::number<Backend, Option> > :boost::mpl::false_ {};

using namespace std;
using namespace boost::numeric::odeint;

typedef boost::multiprecision::mpf_float_100 mpf;
typedef std::vector< mpf > state_type;

struct phase_chain{

    void operator()( const state_type &x , state_type &dxdt , const mpf t ) const
    {
        const size_t N = x.size();
        #pragma omp parallel for schedule(runtime)
        for(size_t i = 1 ; i < N - 1 ; ++i)
        {
            dxdt[i] = x[i+1] - x[i] +
                      x[i-1] - x[i];
        }
        dxdt[0]   = x[1] - x[0];
        dxdt[N-1] = x[N-2] - x[N-1];
    }
};

int main( int argc , char **argv )
{
    size_t N = 1024;
    state_type x( N );
    for (int i = 0; i < N; ++i) x[i] = 1.1;

    bulirsch_stoer< state_type, mpf, state_type, mpf, openmp_range_algebra > stepper(1E-10, 1E-10, 1, 1);

    int chunk_size = N/omp_get_max_threads();
    omp_set_schedule( omp_sched_static , chunk_size );

    integrate_adaptive(stepper, phase_chain(), x, mpf("0.0"), mpf("1.0"), mpf("0.1"));
}

When I replace the mpf type by a double, the code compiles without errors with icpc or g++. However, in this form with boost multiprecision I encounter the following error message, that I cannot get rid of.

/user/boost_1_71_0/boost/numeric/odeint/external/openmp/openmp_range_algebra.hpp(263): error: no matching declaration for this reduction
  #       pragma omp parallel for reduction(max: init) schedule(dynamic)
                                                 ^
          detected during:
            instantiation of "boost::numeric::odeint::norm_result_type<S, void>::type boost::numeric::odeint::openmp_range_algebra::norm_inf(const S &) [with S=state_type]" at line 89 of "/user/boost_1_71_0/boost/numeric/odeint/stepper/controlled_runge_kutta.hpp"
            instantiation of "boost::numeric::odeint::default_error_checker<Value, Algebra, Operations>::value_type boost::numeric::odeint::default_error_checker<Value, Algebra, Operations>::error(boost::numeric::odeint::default_error_checker<Value, Algebra, Operations>::algebra_type &, const State &, const Deriv &, Err &, Time) const [with Value=mpf, Algebra=boost::numeric::odeint::openmp_range_algebra, Operations=boost::numeric::odeint::default_operations, State=state_type, Deriv=state_type,
                      Err=state_type, Time=mpf]" at line 235 of "/user/boost_1_71_0/boost/numeric/odeint/stepper/bulirsch_stoer.hpp"
            instantiation of "boost::numeric::odeint::controlled_step_result={boost::numeric::odeint::controlled_step_result} boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::try_step(System, const StateIn &, const DerivIn &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type &, StateOut &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations,
                      Resizer>::time_type &) [with State=state_type, Value=mpf, Deriv=state_type, Time=mpf, Algebra=boost::numeric::odeint::openmp_range_algebra, Operations=boost::numeric::odeint::default_operations, Resizer=boost::numeric::odeint::initially_resizer, System=phase_chain, StateIn=state_type, DerivIn=state_type, StateOut=state_type]" at line 156 of "/user/boost_1_71_0/boost/numeric/odeint/stepper/bulirsch_stoer.hpp"
            instantiation of "boost::numeric::odeint::controlled_step_result={boost::numeric::odeint::controlled_step_result} boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::try_step(System, StateInOut &, const DerivIn &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type &) [with
                      State=state_type, Value=mpf, Deriv=state_type, Time=mpf, Algebra=boost::numeric::odeint::openmp_range_algebra, Operations=boost::numeric::odeint::default_operations, Resizer=boost::numeric::odeint::initially_resizer, System=phase_chain, StateInOut=state_type, DerivIn=state_type]" at line 393 of "/user/boost_1_71_0/boost/numeric/odeint/stepper/bulirsch_stoer.hpp"
            instantiation of "boost::numeric::odeint::controlled_step_result={boost::numeric::odeint::controlled_step_result} boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::try_step_v1(System, StateInOut &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type &) [with State=state_type,
                      Value=mpf, Deriv=state_type, Time=mpf, Algebra=boost::numeric::odeint::openmp_range_algebra, Operations=boost::numeric::odeint::default_operations, Resizer=boost::numeric::odeint::initially_resizer, System=phase_chain, StateInOut=state_type]" at line 135 of "/user/boost_1_71_0/boost/numeric/odeint/stepper/bulirsch_stoer.hpp"
            instantiation of "boost::numeric::odeint::controlled_step_result={boost::numeric::odeint::controlled_step_result} boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::try_step(System, StateInOut &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type &, boost::numeric::odeint::bulirsch_stoer<State, Value, Deriv, Time, Algebra, Operations, Resizer>::time_type &) [with State=state_type,
                      Value=mpf, Deriv=state_type, Time=mpf, Algebra=boost::numeric::odeint::openmp_range_algebra, Operations=boost::numeric::odeint::default_operations, Resizer=boost::numeric::odeint::initially_resizer, System=phase_chain, StateInOut=state_type]" at line 103 of "/user/boost_1_71_0/boost/numeric/odeint/integrate/detail/integrate_adaptive.hpp"
            instantiation of "size_t={unsigned long} boost::numeric::odeint::detail::integrate_adaptive(Stepper, System, State &, Time &, Time, Time &, Observer, boost::numeric::odeint::controlled_stepper_tag) [with Stepper=boost::numeric::odeint::bulirsch_stoer<state_type, mpf, state_type, mpf, boost::numeric::odeint::openmp_range_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, System=phase_chain, State=state_type, Time=mpf,
                      Observer=boost::numeric::odeint::null_observer]" at line 45 of "/user/boost_1_71_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp"
            instantiation of "size_t={unsigned long} boost::numeric::odeint::integrate_adaptive(Stepper, System, State &, Time, Time, Time, Observer) [with Stepper=boost::numeric::odeint::bulirsch_stoer<state_type, mpf, state_type, mpf, boost::numeric::odeint::openmp_range_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, System=phase_chain, State=state_type, Time=mpf, Observer=boost::numeric::odeint::null_observer]" at line 83 of
                      "/user/boost_1_71_0/boost/numeric/odeint/integrate/integrate_adaptive.hpp"
            instantiation of "size_t={unsigned long} boost::numeric::odeint::integrate_adaptive(Stepper, System, State &, Time, Time, Time) [with Stepper=boost::numeric::odeint::bulirsch_stoer<state_type, mpf, state_type, mpf, boost::numeric::odeint::openmp_range_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, System=phase_chain, State=state_type, Time=mpf]" at line 44 of "phase_chain_parallel_mpf.cpp"

compilation aborted for phase_chain_parallel_mpf.cpp (code 2)

I used for this icpc, boost 1.71.0 on opensuse. Thank you for any kind of help.

Edit: The error message disappeared for some reason after removing the openmp_range_algebra template argument.

来源:https://stackoverflow.com/questions/58354098/how-to-combine-boost-odeint-with-openmp-and-boost-multiprecision

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!