1

多くの初期条件の初期値の問題を解決するために、boost::odeintの lorenz_parameters.cu の例を変更しようとしています。プログラムでセグメンテーション違反が発生しました。これは、の呼び出しにポインタを誤って渡したことが原因であると考えられますintegrate_adaptive()。導関数を格納するためのベクトルのサイズを出力しようとすると、0 になるからです。

参考までに、例のドキュメントと同じ例のコードを次に示します(何らかの理由で、元のドキュメントのコードへのリンクが機能しません)。

プログラムの完全なソース コードを以下に添付しました。UNEXPECTED OUTPUT!微分ベクトルのサイズを出力しようとすると、状態ベクトル (512) と同じサイズの 0 と表示されます。とマークされた行もありますLINE I DO NOT UNDERSTAND。これは、何か間違ったことをしている可能性があると思われる場所です。operator()この行は、intergrate_adaptive() への呼び出しの一部であり、この引数は、(最終的に / odeint パッケージを介して) の関数に渡されるものだと思いますparallel_initial_condition_problem。しかし、例と同じことをしようとしていますが、まだ機能していません。どんな助けでも大歓迎です!

#include <iostream>
#include <vector>
#include <thrust/device_vector.h>
#include <boost/numeric/odeint.hpp>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <typeinfo>

typedef double value_type;

//change this to device_vector< ... > of you want to run on GPU
typedef thrust::host_vector< value_type > state_type;

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

const size_t D = 16; // how many values of each initial condition to try
const size_t N_ICS = D * D; // number of initial conditions
const size_t N_VARS = 2; // number of variables in the system

// time constants
const value_type t_0 = 0.0;
const value_type t_final = 0.1;    
const value_type dt = 0.01;

struct parallel_initial_condition_problem {
  struct functor
  {
    template< class T >
    __host__ __device__
    void operator()( T t ) const
    {
      const value_type k_b = 0.45/6.0;
      const value_type k_f = 1.0;
      const value_type k_d = 1.0;

      // unpack the variables (and the parameters we want to vary, if any)
      value_type f = thrust::get< 0 >( t );
      value_type a = thrust::get< 1 >( t );
      // value_type df = thrust::get< 2 >( t ); // this also causes a segfault
      // value_type da = thrust::get< 3 >( t );
      // calculate the derivative
      thrust::get< 2 >( t ) = -0.01; // minimal value for debugging
      thrust::get< 3 >( t ) = -0.01; 
    }
  };

  parallel_initial_condition_problem( size_t N )
  : m_N( N ) { }

  template< class State , class Deriv >
  void operator()(const State &x , Deriv &dxdt , value_type t ) const
  {
    //// Printing out debugging info (here is the error..but why?)
    cout << "INSIDE operator()" << endl;
    cout << "t: " << t << endl;    
    cout << "size of x: \t" << boost::end(x) - boost::begin(x) << endl;
    cout << "size of dxdt: \t" << boost::end(dxdt) - boost::begin(dxdt) << endl; // UNEXPECTED OUTPUT!!
    cout << endl;

    thrust::for_each(
      thrust::make_zip_iterator( 
        thrust::make_tuple(
               boost::begin( x ) + 0*m_N,
               boost::begin( x ) + 1*m_N ,
               boost::begin( dxdt ) + 0*m_N,
               boost::begin( dxdt ) + 1*m_N
               )
                 ) ,
      thrust::make_zip_iterator( 
        thrust::make_tuple(
               boost::begin( x ) + 1*m_N,
               boost::begin( x ) + 2*m_N ,
               boost::begin( dxdt ) + 3*m_N,
               boost::begin( dxdt ) + 4*m_N
               )
                 ) ,
      functor() );
  }

  size_t m_N;
};

int main(int /* argc */ , char** /* argv */ ) {

  // x stores both (initial) state (x) [0:N_VARS*N_ICS] and dxdt [N_VARS*N_ICS:END]
  state_type x( 2 * N_VARS * N_ICS ); 

  // DUMMY INITIAL CONDITIONS FOR DEBUGGING PURPOSES
  // fill each value with its index
  for(int i=0;i<x.size();i++) {
    x[i] = 0.01+i;
  }

  // system function
  parallel_initial_condition_problem init_con_solver( N_ICS );

  //////////////////////////////// Debugging info: (all seems correct here)
  cout << "POINTERS"  << endl;
  cout << "size of x: " << boost::end(x) - boost::begin(x) << endl;
  cout << "x    :" << &(*x.begin()) << endl;
  cout << "dxdt :" << &(*x.begin()) + N_VARS*N_ICS << endl;
  cout << "end  :" << &(*x.end()) << endl;
  cout << endl;

  /////////////////////////// STATE_T      VALUE_T      DERIV_T      TIME_T
  typedef runge_kutta_dopri5< state_type , value_type , state_type , value_type > stepper_type;
  const value_type abs_err = 1.0e-6;
  const value_type rel_err = 1.0e-6;
  integrate_adaptive( make_controlled( abs_err , rel_err , stepper_type() ),
              init_con_solver ,
              std::make_pair( x.begin() , x.begin() + N_VARS*N_ICS  ), /// LINE I DO NOT UNDERSTAND
              t_0, t_final, dt );

}

これを実行した結果は次のとおりです。

$ g++ main.c && ./a.out
POINTERS
size of x: 1024
x    :0x9a2010
dxdt :0x9a3010
end  :0x9a4010

INSIDE operator()
t: 0
size of x:  512
size of dxdt:   0

Segmentation fault (core dumped)
4

1 に答える 1

1

欠落しているインクルードがあると思います。試してみてください

#include <boost/numeric/odeint/external/thrust/thrust.hpp>

実際、なぜあなたのコードがコンパイルされるのだろうか。boost (1.55) の現在の odeint バージョンを使用する場合は、代数と演算の種類も指定する必要があります。

typedef runge_kutta_dopri5<
    state_type ,
    value_type ,
    state_type ,
    value_type ,
    thrust_algebra ,
    thrust_operations > stepper_type;

これは、次のブースト リリースで変更されるはずです。odeint の gihub バージョンの場合、コードは問題ないはずです。

于 2014-07-24T16:14:27.657 に答える