Как совместить boost odeint с OpenMP и boost multiprecision? - PullRequest
0 голосов
/ 12 октября 2019

Я задаю вопрос, связанный с последними комментариями в этом посте:

Использование openmp с odeint и адаптивными размерами шагов

В конце концов,В оригинальном плакате спрашивалось, совместим ли OpenMP с Boost Multiprecision. Я думаю, что эта проблема была решена в то же время, но я не мог найти ответ.

Поэтому я попытался выяснить это самостоятельно и внедрил несколько связанных ODE.

#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"));
}

Когда я заменяю тип mpf на double, код компилируется без ошибок с помощью icpc или g ++. Тем не менее, в этой форме с повышенной точностью, я вижу следующее сообщение об ошибке, от которого я не могу избавиться.

/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)

Я использовал для этого icpc, повышение 1.71.0 при открытии использования. Спасибо за любую помощь.

Редактировать: Сообщение об ошибке почему-то исчезло после удаления аргумента шаблона openmp_range_algebra.

...